使用Django Rest Framework返回当前用户

Max*_*ime 59 python api django django-rest-framework

我目前正在使用Django开发API.

但是,我想创建一个视图,使用以下端点返回当前用户:/users/current/.

为此,我创建了一个列表视图,并将查询集过滤到发出请求的用户.这是有效的,但结果是一个列表,而不是一个对象.结合分页,结果看起来太复杂,与其他端点不一致.

我还试图创建一个详细视图并过滤查询集,但DRF抱怨我没有提供pk或slug.

你有什么主意吗 ?

Tom*_*tie 61

有了这样的东西,你可能最好打破通用视图并自己编写视图.

@api_view(['GET'])
def current_user(request):
    serializer = UserSerializer(request.user)
    return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)

您也可以使用基于类的视图执行相同的操作,如此...

class CurrentUserView(APIView):
    def get(self, request):
        serializer = UserSerializer(request.user)
        return Response(serializer.data)
Run Code Online (Sandbox Code Playgroud)

当然,也没有要求您使用序列化程序,您也可以从用户实例中提取所需的字段.

@api_view(['GET'])
def current_user(request):
    user = request.user
    return Response({
        'username': user.username,
        'email': user.email,
        ...
    })
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.

  • 注意:我必须使用 `serializer = UserSerializer(request.user, context={'request': request})` 因为我的用户序列化程序包含一个超链接 `url` 字段(基于默认项目)。 (2认同)

Vla*_*kov 23

最好的方法是使用这样的力量viewsets.ModelViewSet:

class UserViewSet(viewsets.ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_object(self):
        pk = self.kwargs.get('pk')

        if pk == "current":
            return self.request.user

        return super(UserViewSet, self).get_object()
Run Code Online (Sandbox Code Playgroud)

viewsets.ModelViewSetmixins.CreateModelMixin+ mixins.RetrieveModelMixin+ mixins.UpdateModelMixin+ mixins.DestroyModelMixin+ mixins.ListModelMixin+ 的组合viewsets.GenericViewSet.如果您只需要列出所有或获得包括当前已通过身份验证的特定用户,则只需将其替换为此类

class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    # ...
Run Code Online (Sandbox Code Playgroud)


Owa*_*one 10

如果由于某种原因必须使用通用视图集,则可以执行以下操作,

class UserViewSet(viewsets.ModelViewSet):
    model = User
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user

    def list(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

retrieve当客户端使用像主键/users/10这样的标识符请求单个实例时,会调用方法,从而正常触发检索方法.检索自己的电话get_object.如果希望视图始终返回当前使用的当前值,则可以通过调用并在其中返回来修改get_object并强制list方法返回单个项而不是列表self.retrieve.


oll*_*amh 8

而不是使用ModelViewSet的全部功能,您可以使用mixins.RetrieveModelMixin用于检索单个对象,就像这里提到的那样 - http://www.django-rest-framework.org/api-guide/viewsets/#example_3

class UserViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    permission_classes = (permissions.IsAuthenticated,)
    queryset = User.objects.all()
    serializer_class = UserSerializer

    def get_object(self):
        return self.request.user
Run Code Online (Sandbox Code Playgroud)

如果您还需要更新模型,只需添加UpdateModelMixin.


小智 7

我使用了像这样的ModelViewSet:

class UserViewSet(viewsets.ModelViewSet):
    model = User
    serializer_class = UserSerializer

    def dispatch(self, request, *args, **kwargs):
        if kwargs.get('pk') == 'current' and request.user:
            kwargs['pk'] = request.user.pk

        return super(UserViewSet, self).dispatch(request, *args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

  • 使用SessionAuthentication.使用TokenAuthentication时不起作用.request.user在调度内部是匿名的. (3认同)