2015-05-23 21 views
17

Attualmente sto implementando djangorestframework per l'API RESTful della mia app. Dopo aver giocato con esso, non riesco ancora a capire chiaramente che cosa sono usati per lo .create(self, validated_data) e .update(self, validated_data) nel serializzatore. Come ho capito, CRUD chiama solo i 4 metodi principali in viewsets.ModelViewSet: create(), retrive(), update() e destroy().Quando vengono creati e aggiornati i file chiamati serializzatore djangorestframework?

Inoltre ho già tentato di eseguire il debug e stampare roba per vedere quando le .create() e .update() metodi sono chiamati sia ModelViewSet e ModelSerializer. Apparentemente, solo i metodi in ModelViewSet vengono chiamati quando eseguo i verbi HTTP. Tuttavia, per ModelSerializer, non vedo alcuna chiamata in questi 2 metodi. Voglio solo sapere quali sono i metodi utilizzati in ModelSerializer poiché vedo che le persone sovrascrivono molto quei metodi nel serializzatore.

P/S: Sono un principiante in djangorestframework + mi dispiace per il mio inglese poiché non sono nativo.

Grazie :)

risposta

50

È davvero necessario dividere le cose tra le visualizzazioni e il serializzatore.

Serializzatori

Il Serializer è un oggetto autonomo. Viene utilizzato per convertire un modello Django (o qualsiasi tipo di datastructure Python, in realtà) in una forma serializzata e viceversa. Puoi usarlo come tale, ovunque tu voglia. Non ha nemmeno bisogno di una richiesta HTTP effettiva se non hai bisogno di URI nel tuo output.

La sottoclasse ModelSerializer è un tipo specializzato di Serializer che aggiunge funzionalità "caricamento da modello" e "salva su modello". Il punto di ingresso "Salva su modello" è il metodo save(). Per facilitare l'override, la sua implementazione predefinita delegherà il proprio lavoro al metodo create() o update() del serializzatore, a seconda che stia creando una nuova istanza di modello o aggiornandola.

Lo scopo è la personalizzazione: offre allo sviluppatore l'opzione per sostituire solo il metodo di creazione, solo il metodo di aggiornamento o il comportamento comune. Per esempio, permette di fare questo genere di cose:

def save(self, **kwargs): 
    # Will be done on every save 
    kwargs['last_changed'] = timezone.now() 
    return super().save(**kwargs) 

def create(self, instance, data): 
    # Will only be done if a new object is being created 
    data['initial_creation'] = timezone.now() 
    return super().create(instance, data) 

Questo è un esempio di base. Qui, il campo last_changed verrà impostato ogni volta che un oggetto viene salvato, sia esso una creazione o un aggiornamento. Come sidenote, probabilmente non vuoi farlo. Cose come l'impostazione dei campi "last_changed" dovrebbero vivere nella vista, non nel serializzatore.

Viewsets

In un luogo completamente diverso, Django RIPOSO forniture quadro Viewsets. Quelli sono una raccolta organizzata di viste, che ruotano attorno all'implementazione di un'API CRUD per un modello. In quanto tale, struttura la funzionalità in un insieme di metodi, ovvero create(), retrieve()/list(), update() e delete().

Il punto principale è: non esiste alcuna connessione tra il metodo create() dello strumento di visualizzazione e il metodo create() del serializzatore.

Accade solo che l'implementazione predefinita dei metodi del viewset utilizza un ModelSerializer e che l'implementazione predefinita del metodo save() delegati che di serializzatore il lavoro ai metodi che hanno lo stesso nome.

A proposito, circa l'esempio last_changed, ecco come si farebbe nella vista:

def perform_create(self, serializer): 
    now = timezone.now() 
    serializer.save(initial_creation=now, last_changed=now) 

def perform_update(self, serializer): 
    serializer.save(last_changed=timezone.now()) 

Questo è funzionalmente equivalente all'esempio precedente, ma vive nel viewset.

Conclusione

Ma torniamo alla tua domanda, la cosa specifica si dovrebbe ignorare dipende da quale oggetto è responsabile per l'attività che si desidera aggiungere.

  • Se il comportamento personalizzato è parte del processo di serializzazione, cioè, il processo di conversione dei dati grezzi di nuovo in una vera e propria modello di Django e salvarlo, allora si dovrebbe sostituire i metodi s' il Serializer.
  • Se, d'altra parte, il comportamento personalizzato è specifico per il proprio gruppo di viste, è necessario sovrascrivere i metodi di Viewset.

Come suggerimento, è possibile porsi la seguente domanda: se uso lo stesso serializzatore in un altro posto (forse un altro viewet), dovrebbe sempre visualizzare tale comportamento?

+1

Grazie per la risposta! È davvero dettagliato e approfondito proprio come quello che voglio. +1 :) – Tim

3

Nella progettazione resto-api Tavola CRUD è uno standard. Non c'è una grande differenza nella creazione e nell'aggiornamento.

prega di fare riferimento al this e

vedere create() metodo creerà un elemento.

e

update() metodo necessario specificare quale elemento per essere aggiornato.

+0

Qual è la differenza tra questi 2? – Tim

13

ho finalmente capito come il lavoro .create() e .update() in Serializer (soprattutto ModelSerializer) e come essi sono collegati a Viewsets (soprattutto ModelViewSet). Voglio solo chiarire il concetto più chiaramente se qualcuno viene a questa domanda.

Fondamentalmente, i 4 metodi CRUD in ModelViewSet: .create(), .retrieve(), .update() e .destroy() gestirà le chiamate da verbi HTTP. Per impostazione predefinita, lo .create() e .update() da ModelViewSet chiamerà il .create() e .update() da ModelSerializer chiamando il metodo .save() dalla classe BaseSerializer.

Il metodo save() sarà quindi determinare se chiamerà .create() o .update() in ModelSerializer determinando se l'oggetto self.instance esiste o no.

Problemi correlati