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 :)
Vous devez vraiment partager les choses entre les vues et le sérialiseur.
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.
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.
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.
Serializer
méthodes.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?
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.