2015-05-19 8 views
6

Utilizzando un ModelViewSet, è normale che get_serializer_class venga chiamato più volte per una singola richiesta, quando si accede all'API sfogliabile? E che il valore di self.method.request cambia tra ogni chiamata?Django Rest Framework: `get_serializer_class` chiamato più volte, con valore errato del metodo di richiesta

Ho creato a small test project to show the behaviour. In project/example/views.py c'è un ThingViewSet con un numero personalizzato get_serializer_class, che stampa il metodo di richiesta corrente.

Se si avvia il server e navigare a http://127.0.0.1:8000/things/1/, l'uscita sarà qualcosa del tipo:

./manage.py runserver 
Performing system checks... 

System check identified no issues (0 silenced). 
May 19, 2015 - 08:51:34 
Django version 1.8.1, using settings 'project.settings' 
Starting development server at http://127.0.0.1:8000/ 
Quit the server with CONTROL-C. 
Method is: GET 
Method is: PUT 
Method is: PATCH 
Method is: PUT 
[19/May/2015 08:51:40]"GET /things/1/ HTTP/1.1" 200 11679 

Chiaramente, get_serializer_class è chiamato 4 volte, con valori diversi (GET, PUT, PATCH, PUT), anche se viene eseguita una sola richiesta GET.

cosa strana è che questo non accade se lo si richiede come JSON:

./manage.py runserver 
Performing system checks... 

System check identified no issues (0 silenced). 
May 19, 2015 - 10:25:57 
Django version 1.8.1, using settings 'project.settings' 
Starting development server at http://127.0.0.1:8000/ 
Quit the server with CONTROL-C. 
Method is: GET 
[19/May/2015 10:26:22]"GET /things/?format=json HTTP/1.1" 200 49 

E il problema è che il metodo di richiesta nel l'ultima chiamata al get_serializer_class delle API sfogliabile è PUT (che è ovviamente sbagliato per una richiesta GET) e quindi finiamo per usare il serializzatore sbagliato per la richiesta, dato che vengono restituiti diversi serializzatori per diversi metodi di richiesta, cosa che facciamo nel nostro progetto reale (ad esempio per operazioni di lettura e scrittura).

Qualcuno può far luce su cosa sta succedendo? Perché lo get_serializer_class viene chiamato più volte per l'API navigabile, con valori di metodo errati?

+0

@KevinBrown Sì, questo si verifica quando si utilizza l'API sfogliabile. Non si verifica quando si richiedono cose come JSON. – decibyte

+0

... E con "come JSON" intendo sia aggiungendo '? Format = json' all'URL, sia tramite un'appropriata intestazione' Accept'. – decibyte

risposta

10

Il motivo per cui si sta vedendo get_serializer_class chiamato più volte è perché si sta utilizzando l'API sfogliabile. Se lo provi senza utilizzare l'API sfogliabile, ad esempio forzando il renderer JSON (?format=json o un'intestazione Accept), lo vedrai solo come uno.

L'API sfogliabile genera i moduli visualizzati in base al serializzatore, pertanto get_serializer_class viene chiamato una volta per ogni modulo e il tipo di richiesta possibile.

Quindi, mentre la prima richiesta, un GET ha senso per il serializzatore originale utilizzato per gestire i dati di risposta (l'oggetto specifico, in questo caso), i tre successivi sono personalizzati per l'API sfogliabile. Queste sono le chiamate che avvengono, nel seguente ordine, per get_serializer che si sta vedendo

  1. The raw PUT form (for entering any request body).
  2. The raw PATCH form.
  3. The full PUT form (contains the instance data by default).

Il method sta cambiando con the override_method with function che emula la richiesta metodo sottoposto a override, che normalmente si verifica in una richiesta POST che necessitava di un metodo diverso.

Problemi correlati