web-dev-qa-db-de.com

Geben Sie den aktuellen Benutzer mit Django Rest Framework zurück

Ich entwickle gerade eine API mit Django.

Allerdings, ich möchte eine Ansicht erstellen, die den aktuellen Benutzer mit dem folgenden Endpunkt zurückgibt: /users/current/.

Zu diesem Zweck habe ich eine Listenansicht erstellt und das Abfrageset nach dem Benutzer gefiltert, der die Anforderung gestellt hat. Das funktioniert, aber das Ergebnis ist eine Liste, kein einzelnes Objekt. In Kombination mit der Paginierung erscheint das Ergebnis im Vergleich zu anderen Endpunkten viel zu kompliziert und widersprüchlich.

Ich habe auch versucht, eine Detailansicht zu erstellen und den Abfragesatz zu filtern, aber DRF beklagt sich, dass ich weder pk noch slug angegeben habe.

Hast du irgendeine Idee?

57
Maxime

Mit so etwas ist es wahrscheinlich am besten, wenn Sie aus den allgemeinen Ansichten ausbrechen und die Ansicht selbst schreiben.

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

Sie können dasselbe auch mit einer klassenbasierten Ansicht tun ...

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

Natürlich ist es auch nicht erforderlich, dass Sie einen Serializer verwenden. Sie können auch einfach die benötigten Felder aus der Benutzerinstanz ziehen.

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

Ich hoffe, das hilft.

59
Tom Christie

Der beste Weg ist, die Potenz von viewsets.ModelViewSet Wie folgt zu nutzen:

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.ModelViewSet Ist eine Kombination aus mixins.CreateModelMixin + mixins.RetrieveModelMixin + mixins.UpdateModelMixin + mixins.DestroyModelMixin + mixins.ListModelMixin + viewsets.GenericViewSet. Wenn Sie nur alle auflisten müssen oder einen bestimmten Benutzer einschließlich der aktuell authentifizierten Benutzer erhalten möchten, müssen Sie ihn einfach so ersetzen

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

Wenn Sie aus irgendeinem Grund die generische Ansicht verwenden müssen, können Sie Folgendes tun:

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)

Die Methode retrieve wird aufgerufen, wenn der Client eine einzelne Instanz anfordert, die einen Bezeichner wie einen Primärschlüssel verwendet. /users/10 würde die Abrufmethode normal auslösen. Abrufen selbst ruft get_object Auf. Wenn Sie möchten, dass die Ansicht immer den aktuell verwendeten zurückgibt, können Sie die get_object - Methode ändern und list erzwingen, dass ein einzelnes Element anstelle einer Liste zurückgegeben wird, indem Sie self.retrieve Aufrufen und zurückgeben es.

9
Owais Lone

Ich habe ein ModelViewSet wie folgt verwendet:

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)
7
ejb

Anstelle der vollen Leistung von ModelViewSet können Sie auch Mixins verwenden. Es gibt RetrieveModelMixin, um einzelne Objekte abzurufen, so wie es hier erwähnt wird - http://www.Django-rest-framework.org/api-guide/viewsets/#example_

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

Wenn Sie auch Ihr Modell aktualisieren müssen, fügen Sie einfach UpdateModelMixin hinzu.

7
ollamh