返回当前用户的详细信息

时间:2013-12-31 11:38:11

标签: django django-rest-framework

我正在尝试构建一个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怎么样的建议?

3 个答案:

答案 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类,然后你想要它然后在你需要的每个视图中继承它。假设你有一个有效的解决方案,但只是穿上我不想模仿你到处的代码。