我正在尝试构建一个API视图,使用django 1.6继承框架版本2.3.10来处理用户管理。我尝试构建一个基于URL pk值的ModelViewSet
,它将返回当前用户或公共用户。
我尝试添加一个调度函数,它将pk分配给当前用户,但似乎这个函数运行得太快,以至于它始终将用户视为匿名
class UserViewSet(viewsets.ModelViewSet):
"""
"""
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsOwnerOrCreateOnly, )
def dispatch(self, request, *args, **kwargs):
if kwargs.get('pk') == 'current' and not request.user.is_anonymous():
kwargs['pk'] = request.user.pk
resp = super(CurrentUserViewSet, self).dispatch(request, *args, **kwargs)
return resp
我尝试执行以下操作
class UserViewSet(viewsets.ModelViewSet):
"""
"""
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsOwnerOrCreateOnly, )
def retrieve(self, request, *args, **kwargs):
if self.kwargs.get('pk') == u'current' and not request.user.is_anonymous():
self.kwargs['pk'] = request.user.pk
return super(CurrentUserViewSet, self).retrieve(request, *args, **kwargs)
但是,我不想覆盖我所拥有的几个ModelViewSet
类的每个函数,所以,有没有办法使用类似于调度程序的东西,我可以检查pk是否等于“当前”然后将当前用户分配给它?
另一个问题是,如何以编程方式更改返回的字段?例如,在查询当前用户时,我想要包含用户模型中的名字和姓氏,但是当按主键查询时,我希望名字和姓氏不作为响应返回?关于todo怎么样的建议?
答案 0 :(得分:1)
我遇到了同样的问题,我通过使用方法“initial”而不是“dispatch”来解决它
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsOwnerOrCreateOnly, )
def initial(self, request, *args, **kwargs):
# logic - code #
if kwargs.get('pk') == 'current' and not request.user.is_anonymous():
kwargs['pk'] = request.user.pk
# end #
resp = super(CurrentUserViewSet, self).initial(request, *args, **kwargs)
return resp
见“派遣” https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/views.py中的方法 为了更好地理解。
答案 1 :(得分:0)
用你的pk check实现覆盖viewsets.ModelViewSet
类并使用那个新类,如下所示:
class GenericUserViewSet(viewsets.ModelViewSet):
def retrieve(self, request, *args, **kwargs):
if self.kwargs.get('pk') == u'current' and not request.user.is_anonymous():
self.kwargs['pk'] = request.user.pk
return super(CurrentUserViewSet, self).retrieve(request, *args, **kwargs)
class UserViewSet(GenericUserViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsOwnerOrCreateOnly, )
对于第二个问题,也许创建两个序列化程序(公共和当前)并将serializer_class
更改为init
GenericUserViewSet
中的任何一个都可以做到这一点,我没有'测试了这个,但这是一个想法:
class GenericUserViewSet(viewsets.ModelViewSet):
def __init__(self, *args, **kwargs):
if self.kwargs.get('pk') == u'current' and not request.user.is_anonymous():
self.serializer_class = UserSerializer
else:
self.serializer_class = PublicUserSerializer
super(GenericUserViewSet, self).__init__(*args, **kwargs)
答案 2 :(得分:0)
我假设你想将当前用户保存到你的数据库模型,是吗?
如果是这样,这应该很容易修复,只需将此方法添加到您的视图中:
def pre_save(self, obj):
obj.user = self.request.user
这将在模型保存之前执行。我一直都在使用它,效果很好。
你可以做的另一件事就是以通用的方式编写一个mixin类,然后你想要它然后在你需要的每个视图中继承它。假设你有一个有效的解决方案,但只是穿上我不想模仿你到处的代码。