Quiero aclarar la documentación dada de django-rest-framework
respecto a la creación de un objeto modelo. Hasta ahora he encontrado que hay tres enfoques sobre cómo manejar tales eventos.
El método create()
del serializador. Aquí está la documentación.
class CommentSerializer(serializers.Serializer): def create(self, validated_data): return Comment.objects.create(**validated_data)
El método ModelViewset create()
. Documentación
class AccountViewSet(viewsets.ModelViewSet): queryset = Account.objects.all() serializer_class = AccountSerializer permission_classes = [IsAccountAdminOrReadOnly]
El método ModelViewset perform_create()
. Documentación
class SnippetViewSet(viewsets.ModelViewSet): def perform_create(self, serializer): serializer.save(owner=self.request.user)
Este enfoque de tres es importante dependiendo de su entorno de aplicación.
Pero ¿CUÁNDO necesitamos usar cada función create() / perform_create()
? Por otra parte, encontré que algunos métodos de creación fueron llamados para una sola solicitud de publicación. El create()
modelviewset y el create()
serializador.
Espero que alguien pueda compartir algo de su conocimiento para explicar y esto seguramente será muy útil en mi proceso de desarrollo.
create(self, validated_data)
para agregar cualquier detalle adicional en el objeto antes de guardar Y “prod” valores en cada campo del modelo como lo hace **validated_data
. Hablando de manera ideal, quiere hacer esta forma de “pinchar” solo en UNA ubicación para que el método de create
en su CommentSerializer
sea el mejor. Además de esto, es posible que también desee llamar a apis externas para crear cuentas de usuario de su lado justo antes de guardar sus cuentas en su propia base de datos. Debe utilizar esta función de create
junto con ModelViewSet
. Siempre piensa – “Vistas finas, serializadores gruesos”. Ejemplo:
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 función create(self, request, *args, **kwargs)
en ModelViewSet
se define en la clase CreateModelMixin
, que es la principal de ModelViewSet
. CreateModelMixin
principales funciones de CreateModelMixin
son estas:
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()
Como puede ver, la función de create
anterior se encarga de llamar a la validación de su serializador y de producir la respuesta correcta. La belleza detrás de esto, es que ahora puede aislar la lógica de su aplicación y NO preocuparse por las llamadas de validación mundanas y repetitivas y el manejo de la respuesta de respuesta :). Esto funciona bastante bien junto con la create(self, validated_data)
encuentra en el serializador (donde podría residir la lógica de la aplicación específica).
perform_create(self, serializer)
con una sola línea de código? Bueno, la razón principal detrás de esto es permitir la personalización al llamar a la función de save
. Es posible que desee proporcionar datos adicionales antes de llamar a save
(como serializer.save(owner=self.request.user)
y si no perform_create(self, serializer)
, tendría que anular la create(self, request, *args, **kwargs)
y eso simplemente create(self, request, *args, **kwargs)
el propósito de tener mixins haciendo el trabajo pesado y aburrido. ¡Espero que esto ayude!