2015-05-23 5 views
5

Nel mio codice ho un viewet per l'utente. Voglio consentire solo le operazioni di lettura (/users/42 e /users/) che ReadOnlyModelViewSet funziona correttamente.django rest framework - using detail_route e detail_list

Inoltre, voglio avere un/utenti/registrare URL che posso POST al fine di registrare un nuovo utente.

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) 

paio di domande:

  • Questo sarebbe questo il modo giusto di fare questo?

  • Esiste una specifica firma per un metodo se lo metto in un list_route o detail_route decoratore? perché negli esempi detail_route la sua sempre la stessa firma per il metodo: nome_metodo (auto, richiesta, pk = None):

grazie!

risposta

7

Il codice è quasi corretto, sei solo manca la firma proprio sul metodo di registro:

def register(self, request): 

Questa è la firma corretta secondo the documentation. Inoltre the tests suggerire che non è possibile passare un parametro aggiuntivo per il routing, e che pk sarà sempre essere passato per un @detail_route, quindi si dovrebbe avere:

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

per le rotte di dettaglio e

@list_route 
def register(self, request): 

per i percorsi elenco.

Tuttavia vorrei suggerire di sfruttare il costruito nel ViewSetMixins as ModelViewSet does internally:

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) 

Per segno utente up in generale, si può anche dare un'occhiata a django-registration-restframework che attualmente sto facendo il lavoro per il mio progetto.

Personalmente mi affido a ModelViewSet nei miei progetti e mi assicuro che solo gli utenti autorizzati possano eseguire determinate azioni. Per fare ciò è possibile utilizzare il modello permissions o in combinazione con le autorizzazioni specifiche dell'oggetto django guardian.

Specialmente con un'API REST, arriverete al punto che vorreste che determinati utenti eseguissero azioni solo su determinati oggetti, senza dover eseguire il microgestione di ogni richiesta. Le autorizzazioni a livello di oggetto possono essere di grande utilità qui.

+1

grazie per la risposta, darò un'occhiata. una domanda: ModelviewSet consente di ottenere GET, POST, PATCH, GET e DELETE. quando si sostituisce il metodo di aggiornamento e si genera un NotAllowed - sarà valido solo per POST e PATCH? o anche per DELETE?Voglio dire copre tutti i metodi oltre a GET e POST per creare? sto solo cercando di assicurarmi che permetta solo i metodi desiderabili –

+0

Hai assolutamente ragione. Ho modificato il codice per usare i mixin corretti in modo esplicito, invece di rattoppare il codice di modifica. –