Je veux clarifier la documentation donnée de Django-rest-framework
Concernant la création d'un objet de modèle. Jusqu'ici, j'ai trouvé qu'il y avait 3 approches sur la façon de gérer de tels événements.
La méthode create()
du sérialiseur. Voici le documentation
class CommentSerializer(serializers.Serializer):
def create(self, validated_data):
return Comment.objects.create(**validated_data)
La méthode ModelViewset create()
. Documentation
class AccountViewSet(viewsets.ModelViewSet):
queryset = Account.objects.all()
serializer_class = AccountSerializer
permission_classes = [IsAccountAdminOrReadOnly]
La méthode ModelViewset perform_create()
. Documentation
class SnippetViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
Ces trois approches sont importantes en fonction de votre environnement d'application.
Mais QUAND devons-nous utiliser chaque fonction create() / perform_create()
??. D'autre part, j'ai trouvé un compte qui indique que deux méthodes de création ont été appelées pour une demande de publication unique, à savoir create()
de modelviewset et create()
du sérialiseur.
Espérons que tout le monde partagera certaines de ses connaissances pour les expliquer, ce qui sera certainement très utile dans mon processus de développement.
create(self, validated_data)
pour ajouter des détails supplémentaires à l'objet avant d'enregistrer des valeurs AND "prod" dans chaque champ de modèle, comme le fait **validated_data
. Dans l’idéal, vous voulez utiliser cette forme de "repérage" dans un seul emplacement, de sorte que la méthode create
dans votre CommentSerializer
est le meilleur endroit. En plus de cela, vous pouvez également appeler des API externes pour créer des comptes utilisateur de leur côté juste avant de sauvegarder vos comptes dans votre propre base de données. Vous devriez utiliser cette fonction create
en conjonction avec ModelViewSet
. Pensez toujours - "Vues fines, sérialiseurs épais".Exemple:
def create(self, validated_data):
email = validated.data.get("email", None)
validated.pop("email")
# Now you have a clean valid email
# You might want to call an external API or modify another table
# (eg. keep track of number of accounts registered.) or even
# make changes to the email format.
# Once you are done, create the instance with the validated data
return models.YourModel.objects.create(email=email, **validated_data)
La fonction create(self, request, *args, **kwargs)
dans ModelViewSet
est définie dans la classe CreateModelMixin
qui est le parent de ModelViewSet
. Les fonctions principales de CreateModelMixin
sont les suivantes:
from rest_framework import status
from rest_framework.response import Response
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
def perform_create(self, serializer):
serializer.save()
Comme vous pouvez le constater, la fonction create
ci-dessus prend en charge l’appel de validation sur votre sérialiseur et la réponse correcte. La beauté derrière cela est que vous pouvez maintenant isoler la logique de votre application et ne PAS vous préoccuper des appels de validation banals et répétitifs et du traitement de la sortie de réponse :). Cela fonctionne assez bien avec le create(self, validated_data)
trouvé dans le sérialiseur (où la logique de votre application spécifique pourrait résider).
perform_create(self, serializer)
avec une seule ligne de code!?!? Eh bien, la raison principale derrière cela est de permettre la personnalisation lors de l’appel de la fonction save
. Vous voudrez peut-être fournir des données supplémentaires avant d'appeler save
(comme serializer.save(owner=self.request.user)
et si nous n'avions pas perform_create(self, serializer)
, vous devrez remplacer le create(self, request, *args, **kwargs)
et cela va à l'encontre du but de faire en sorte que mixins effectue le travail lourd et ennuyeux.J'espère que cela t'aides!