Python 使用 Django Rest Framework 返回当前用户

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15770488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:56:57  来源:igfitidea点击:

Return the current user with Django Rest Framework

pythondjangoapidjango-rest-framework

提问by Maxime

I am currently developing an API using Django.

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

However, I would like to create a view that returns the current User with the following endpoint: /users/current/.

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

To do so, I created a list view and filtered the queryset on the user that made the request. That works, but the result is a list, not a single object. Combined with pagination, the result looks way too complicated and inconsistent compared to other endpoints.

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

I also tried to create a detail view and filtering the queryset, but DRF complains that I provided no pk or slug.

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

Do you have any idea?

你有什么主意吗?

采纳答案by Tom Christie

With something like this you're probably best off breaking out of the generic views and writing the view yourself.

有了这样的东西,你可能最好摆脱通用视图并自己编写视图。

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

You could also do the same thing using a class based view like so...

您也可以使用基于类的视图来做同样的事情......

class CurrentUserView(APIView):
    def get(self, request):
        serializer = UserSerializer(request.user)
        return Response(serializer.data)

Of course, there's also no requirement that you use a serializer, you could equally well just pull out the fields you need from the user instance.

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

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

Hope that helps.

希望有帮助。

回答by ejb

I used a ModelViewSet like this:

我使用了这样的 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)

回答by Owais Lone

If you must use the generic view set for some reason, you could do something like this,

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

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)

retrievemethod is called when the client requests a single instance using an identifier like a primary key /users/10would trigger the retrieve method normally. Retrieve itself calls get_object. If you want the view to always return the current used then you could modify get_objectand force listmethod to return a single item instead of a list by calling and returning self.retrieveinside it.

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

回答by ollamh

Instead of using full power of ModelViewSet you can use mixins. There is RetrieveModelMixin used to retrieve single object just like it is mentioned here - http://www.django-rest-framework.org/api-guide/viewsets/#example_3

您可以使用 mixins,而不是使用 ModelViewSet 的全部功能。有 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

If you need also update your model, just add UpdateModelMixin.

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

回答by Vladimir Prudnikov

The best way is to use the power of viewsets.ModelViewSetlike so:

最好的方法是使用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()

viewsets.ModelViewSetis a combination of mixins.CreateModelMixin+ mixins.RetrieveModelMixin+ mixins.UpdateModelMixin+ mixins.DestroyModelMixin+ mixins.ListModelMixin+ viewsets.GenericViewSet. If you need just list all or get particular user including currently authenticated you need just replace it like this

viewsets.ModelViewSetmixins.CreateModelMixin+ mixins.RetrieveModelMixin+ mixins.UpdateModelMixin+ mixins.DestroyModelMixin+ mixins.ListModelMixin+的组合viewsets.GenericViewSet。如果您只需要列出所有或获取特定用户,包括当前已通过身份验证的用户,您只需像这样替换它

class UserViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, viewsets.GenericViewSet):
    # ...