2015-08-07 10 views
6

In DRF, ho un semplice ViewSet come questo:Django REST quadro: metodo PUT non consentito in ViewSet con l'aggiornamento DEF()

class MyViewSet(viewsets.ViewSet):  

    def update(self, request): 
     # do things... 
     return Response(status=status.HTTP_200_OK) 

Quando provo una richiesta PUT, ottengo un errore come metodo PUT non permesso. Se utilizzo def put(self, request):, tutte le cose funzionano correttamente. Di conseguenza a the docs dovrei usare def update(): non def put():, perché succede?

risposta

2

Questo perché il APIView ha alcun gestore definito per .put() metodo così la richiesta in ingresso non può essere associata a un metodo del gestore sulla vista, aumentando così un'eccezione.

(Nota: viewsets.ViewSet Eredita da ViewSetMixin e APIView)

Il metodo dispatch() nei APIView controlla se è definito un gestore metodo per la richiesta method .Se il metodo dispatch() trova un gestore per il metodo di richiesta, restituisce la risposta appropriata. Altrimenti solleva un'eccezione MethodNotAllowed.

Come per il codice sorgente di dispatch() metodo nella classe APIView:

def dispatch(self, request, *args, **kwargs):  
     ... 
     ...  
     try: 
      self.initial(request, *args, **kwargs) 

      # Get the appropriate handler method 
      if request.method.lower() in self.http_method_names: 
       # here handler is fetched for the request method 
       # `http_method_not_allowed` handler is assigned if no handler was found 
       handler = getattr(self, request.method.lower(), 
            self.http_method_not_allowed) 
      else: 
       handler = self.http_method_not_allowed 

      response = handler(request, *args, **kwargs) # handler is called here 

     except Exception as exc: 
      response = self.handle_exception(exc) 

     self.response = self.finalize_response(request, response, *args, **kwargs) 
     return self.response 

Dal .put() metodo del gestore non è definito nella vista, DRF chiama il gestore fallback .http_method_not_allowed. Ciò solleva un'eccezione MethodNotAllowed.

Il codice sorgente per .http_method_not_allowed() è:

def http_method_not_allowed(self, request, *args, **kwargs): 
    """ 
    If `request.method` does not correspond to a handler method, 
    determine what kind of exception to raise. 
    """ 
    raise exceptions.MethodNotAllowed(request.method) # raise an exception 

perché ha funzionato al momento della definizione .put() nel vostro punto di vista?

Quando è stato definito def put(self, request): nella propria visualizzazione, DRF può associare il metodo di richiesta in ingresso a un metodo gestore nella vista. Ciò ha comportato il ritorno di una risposta appropriata senza che fosse sollevata un'eccezione.

+0

Quindi, se ho voluto usare creare lo farei basta mapparlo? – floatingpurr

+0

Hai definito un 'router' nei tuoi url quando definisci' update() 'nella tua vista? –

+0

Ho definito un router per registrare viewSet – floatingpurr

7

Aveva un simile "metodo PUT non consentito" problema con questo codice, perche 'id' mancava nella richiesta:

class ProfileStep2Serializer(serializers.ModelSerializer): 
    class Meta: 
     model = Profile 
     fields = ('middle_initial', 'mobile_phone', 'address', 'apt_unit_num', 'city', 'state', 'zip') 

class Step2ViewSet(viewsets.ModelViewSet): 
    serializer_class = ProfileStep2Serializer 

    def get_queryset(self): 
     return Profile.objects.filter(pk=self.request.user.profile.id) 

scoperto che ho perso 'id' nei campi serializzatore, così La richiesta PUT NON è stata in grado di fornire un ID per il record. La versione fissa del serializzatore è qui sotto:

class ProfileStep2Serializer(serializers.ModelSerializer): 
    class Meta: 
     model = Profile 
     fields = ('id', 'middle_initial', 'mobile_phone', 'address', 'apt_unit_num', 'city', 'state', 'zip') 
4

volte è diverso per POST e PUT, perché PUT utilizza id URL In questo caso yoy'll ottenere questo errore: "PUT è non consentito ".

Esempio:

  • POST: /api/users/
  • PUT: /api/users/1/

Spero che risparmia un sacco di tempo per qualcuno

+0

Si noti che se si definisce semplicemente il metodo 'put' (invece di' update' tramite il mixaggio DRF), funzionerà senza ID. – Ben