python - retrieve - serializer context



Quando usar o create() do Serializer e create() perform_create() do ModelViewset (1)

Eu quero esclarecer a documentação dada do django-rest-framework sobre a criação de um objeto de modelo. Até agora, descobri que existem três abordagens sobre como lidar com esses eventos.

  1. O método create() do Serializer. Aqui está a documentation

    class CommentSerializer(serializers.Serializer):
    
        def create(self, validated_data):
            return Comment.objects.create(**validated_data)
  2. O método createView create() ModelViewset create() . Documentation

    class AccountViewSet(viewsets.ModelViewSet):
    
        queryset = Account.objects.all()
        serializer_class = AccountSerializer
        permission_classes = [IsAccountAdminOrReadOnly]
  3. O método perform_create() ModelViewset. Documentation

    class SnippetViewSet(viewsets.ModelViewSet):
    
        def perform_create(self, serializer):
            serializer.save(owner=self.request.user)

Essas três abordagens são importantes, dependendo do ambiente do seu aplicativo.

Mas quando precisamos usar cada função create() / perform_create() ? Por outro lado, eu encontrei alguma conta que dois métodos de criação foram chamados para uma única solicitação de postagem do create() do modelviewset e do create() serializador.

Espero que alguém compartilhe alguns dos seus conhecimentos para explicar e isso certamente será muito útil no meu processo de desenvolvimento.

https://src-bin.com


Answer #1
  1. Você usaria create(self, validated_data) para adicionar detalhes extras ao objeto antes de salvar os valores de AND "prod" em cada campo de modelo, da mesma forma que **validated_data . Idealmente falando, você quer fazer essa forma de "cutucar" somente em um local, então o método de create no seu CommentSerializer é o melhor lugar. Além disso, convém também chamar apis externas para criar contas de usuários ao lado delas antes de salvar suas contas em seu próprio banco de dados. Você deve usar essa função create em conjunto com ModelViewSet . Sempre pense - "Thin views, Thick serializers".

Exemplo:

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)
  1. A função create(self, request, *args, **kwargs) no ModelViewSet é definida na classe CreateModelMixin que é o pai do ModelViewSet . CreateModelMixin principais funções do CreateModelMixin são estas:

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

Como você pode ver, a função create acima cuida de chamar a validação em seu serializador e produzir a resposta correta. A beleza por trás disso, é que agora você pode isolar sua lógica de aplicativo e NÃO se preocupar com as chamadas de validação mundanas e repetitivas e lidar com a saída de resposta :). Isso funciona muito bem em conjunto com a create(self, validated_data) encontrada no serializador (onde sua lógica de aplicativo específica pode residir).

  1. Agora você pode perguntar, por que temos uma função perform_create(self, serializer) separada com apenas uma linha de código!?!? Bem, a principal razão por trás disso é permitir a personalização ao chamar a função de save . Você pode querer fornecer dados extras antes de chamar save (como serializer.save(owner=self.request.user) e se não tivéssemos perform_create(self, serializer) , você teria que sobrescrever o create(self, request, *args, **kwargs) e que apenas derrota o propósito de ter mixins fazendo o trabalho pesado e chato.

Espero que isto ajude!





django-rest-framework