web-dev-qa-db-fra.com

Quand la création et la mise à jour sont-elles appelées dans le sérialiseur djangorestframework?

J'implémente actuellement djangorestframework pour mon application RESTful API. Après avoir joué avec, je ne comprends toujours pas clairement à quoi servent .create(self, validated_data) et .update(self, validated_data) dans le sérialiseur. Si je comprends bien, CRUD appelle uniquement les 4 méthodes principales dans viewsets.ModelViewSet: create(), retrive(), update() et destroy().

J'ai également déjà essayé de déboguer et d'imprimer des trucs pour voir quand les méthodes .create() et .update() sont appelées à la fois ModelViewSet et ModelSerializer. Apparemment, seules les méthodes de ModelViewSet sont appelées lorsque je fais les verbes HTTP. Cependant, pour ModelSerializer, je ne vois aucun appel dans ces 2 méthodes. Je veux juste savoir à quoi servent ces méthodes dans ModelSerializer car je vois que les gens écrasent beaucoup ces méthodes dans le sérialiseur.

P/S: Je suis un débutant dans djangorestframework + désolé pour mon anglais car je ne suis pas natif.

Merci :)

25
Tim

Vous devez vraiment partager les choses entre les vues et le sérialiseur.

Sérialiseurs

Serializer est un objet autonome. Il est utilisé pour convertir un Django modèle (ou tout type de python datastructure, en fait) en une forme sérialisée, et inversement. Vous pouvez utiliser il en tant que tel, où vous voulez. Il n'a même pas besoin d'une requête HTTP réelle tant que vous n'avez pas besoin d'URI dans votre sortie.

La sous-classe ModelSerializer est un type spécialisé de Serializer qui ajoute des fonctionnalités de "chargement à partir du modèle" et de "sauvegarde sur modèle". Le point d'entrée "enregistrer dans le modèle" est la méthode save(). Pour un remplacement plus facile, son implémentation par défaut déléguera son travail à la méthode create() ou ̀update() du sérialiseur, selon qu'il crée une nouvelle instance de modèle ou en met à jour une.

Le but de cela est la personnalisation: cela vous donne, au développeur, la possibilité de remplacer uniquement la méthode de création, uniquement la méthode de mise à jour ou un comportement courant. Par exemple, cela vous permet de faire ce genre de choses:

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)

Voilà un exemple de base. Là, le champ last_changed Sera défini à chaque fois qu'un objet est enregistré, que ce soit une création ou une mise à jour. En tant que sidenote, vous ne voulez probablement pas faire cela. Des choses telles que la définition des champs "last_changed" doivent vivre dans la vue, pas dans le sérialiseur.

Ensembles de vues

Dans un endroit complètement différent, Django REST fournit Viewsets. Il s'agit d'une collection organisée de vues, qui tourne autour de l'implémentation d'une API CRUD pour un modèle. En tant que tel, il structure sa fonctionnalité en un ensemble de méthodes, à savoir create(), retrieve()/list(), update() et delete().

Le point principal étant: il n'y a absolument aucun lien entre la méthode create() de l'ensemble de vues et la méthode create() du sérialiseur.

Il se trouve que l'implémentation par défaut des méthodes de l'ensemble de vues utilise un ModelSerializer et que l'implémentation par défaut de la méthode save() de ce sérialiseur délègue le travail aux méthodes portant le même nom.

À propos, à propos de l'exemple last_changed, Voici comment vous le feriez dans la vue:

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())

C'est fonctionnellement équivalent à l'exemple ci-dessus, mais il vit dans l'ensemble de vues.

Conclusion

Revenons donc à votre question, la chose spécifique que vous devez remplacer dépend de l'objet qui est responsable de la tâche que vous souhaitez ajouter.

  • Si votre comportement personnalisé fait partie du processus de sérialisation, c'est-à-dire le processus de reconversion des données brutes en un bon modèle Django et en l'enregistrant, vous devez remplacer les Serializer méthodes.
  • Si, en revanche, votre comportement personnalisé est spécifique à votre ensemble de vues, vous devez remplacer les méthodes de Viewset.

À titre indicatif, vous pouvez vous poser la question suivante: si j'utilise le même sérialiseur à un autre endroit (peut-être un autre ensemble de vues), devrait-il toujours afficher ce comportement?

63
spectras

Je comprends enfin comment les .create() et .update() fonctionnent dans Serializer (en particulier ModelSerializer) et comment ils sont connectés à Viewsets ( en particulier ModelViewSet). Je veux juste clarifier le concept plus clairement si quelqu'un vient à cette question.

Fondamentalement, les 4 méthodes CRUD in ModelViewSet: .create(), .retrieve(), .update() et .destroy() traiteront les appels des verbes HTTP. Par défaut, la .create() et .update() de ModelViewSet appellera la .create() et .update() de ModelSerializer en appelant la .save() méthode de la classe BaseSerializer.

La méthode save () déterminera ensuite si elle appellera .create() ou .update() dans ModelSerializer en déterminant si l'objet self.instance existe ou non.

14
Tim

Dans la conception rest-api, créer, lire, mettre à jour et supprimer est une norme. Il n'y a pas de grande différence dans la création et la mise à jour.

Veuillez vous référer à this et

voir la méthode create () créera un élément.

et

pdate () La méthode doit spécifier l'élément à mettre à jour.

3
Vaibhav Mule