webentwicklung-frage-antwort-db.com.de

django Rest Framework - mit detail_route und detail_list

In meinem Code habe ich ein Viewset für den Benutzer. Ich möchte nur Leseoperationen zulassen (/ users/42 und / users /), die ReadOnlyModelViewSet ausführt Alles gut.

Außerdem möchte ich eine / users/register URL haben, zu der ich POST _ kann, um einen neuen Benutzer zu registrieren.

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

    @list_route(methods=['post'])
    def register(request):
        serializer = UserSerializer(data=request.DATA)
        if serializer.is_valid():
            user = User.objects.create_user(
                username = serializer.init_data['username'],
                password = serializer.init_data['password'],
            )

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Paar fragen:

  • Wäre dies der richtige Weg, dies zu tun?

  • Gibt es ein bestimmtes Signatur für eine Methode, wenn ich es in einen list_route oder den detail_route Dekorator stecke? weil in den detail_route-Beispielen immer die gleiche Signatur für die Methode gilt: method_name (self, request, pk = None):

vielen Dank! 

8
Ofek Agmon

Ihr Code ist fast korrekt, Sie vermissen nur die richtige Signatur bei der Registermethode:

def register(self, request):

Dies ist die korrekte Signatur gemäß der Dokumentation . the tests legt außerdem nahe, dass es nicht möglich ist, einen zusätzlichen Parameter für das Routing zu übergeben, und dass pk immer für einen @detail_route übergeben wird, sodass Sie Folgendes benötigen:

@detail_route
def register(self, request, pk=None):

für Detailrouten und 

@list_route
def register(self, request):

für Listenrouten.

Ich würde jedoch vorschlagen, dass Sie die eingebauten ViewSetMixins nutzen, wie ModelViewSet dies intern tut :

from rest_framework import exceptions, mixins
class UserViewSet(mixins.CreateModelMixin,
               mixins.RetrieveModelMixin,
               mixins.ListModelMixin,
               GenericViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer
    def create(self, request):
        serializer = UserSerializer(data=request.DATA)
            if serializer.is_valid():
                user = User.objects.create_user(
                    username = serializer.init_data['username'],
                    password = serializer.init_data['password'],
                )

                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Für Benutzeranmeldungen im Allgemeinen können Sie auch einen Blick auf Django-registration-restframework werfen, den ich gerade für mein Projekt arbeite.

Persönlich verlasse ich mich in meinen Projekten auf das ModelViewSet und stelle sicher, dass nur ordnungsgemäß befugte Benutzer bestimmte Aktionen ausführen können. Dazu können Sie modellweite permissions oder in Kombination mit Django guardian object-spezifischen Berechtigungen verwenden.

Insbesondere mit einer REST -API werden Sie letztendlich zu dem Punkt kommen, dass bestimmte Benutzer nur Aktionen für bestimmte Objekte ausführen sollen, ohne jede Anforderung mit einem Mikromanagement versehen zu müssen. Berechtigungen auf Objektebene können hier von großem Nutzen sein.

12
Sebastian Wozny

detail_route und detail_list werden für DRF 3.0 nicht mehr empfohlen, stattdessen @action:

from rest_framework.decorators import action
    @action(methods=['POST'], detail=True)
    def sale(self):
       ...

Use detail = True, wenn diese Methode eine einzelne Instanz des durch diesen Endpunkt dargestellten Modells berücksichtigt, und False, wenn ein Queryset dieses Modells dargestellt werden muss

0
Gregory