[Django Rest Framework] Dúvida: Como validated_data é manipulado em um Serializer

Oi Turma! Se alguem puder me ajudar, quero aprofundar meu entendimento em DRJ e estou patinando em uma coisa esssncial... :(

Estou com uma dúvida inicial para entender e fixar bem o funcionamento de um serializer, tenho um código que recebe através de um HTTP Post Request com o Body:

{ "description": "Avaliação com Competencias", "employee": 1 }

def post(self, request):
        serializer = EvaluationSerializer(data = request.data, context={"request": request})
        if serializer.is_valid():
            serializer.save()
            return Response("OK")
        else:
            return Response(data=serializer.errors, status=status.HTTP_400_BAD_REQUEST)

O serializer seria algo como:

class EvaluationSerializer(serializers.ModelSerializer):

    description = serializers.CharField(min_length = 5)
    
    def create(self, validated_data):
        evaluation = super(EvaluationSerializer, self).create(validated_data)
        user = User.objects.get(id=validated_data["employee"].id)

Eu não entendo o que acontece por baixo dos panos, pois se eu uso

user = User.objects.get(id=validated_data["employee"])

dá erro, pois idestá recebendo um objeto do tipo User, mas na verdade eu enviei "employee": 1 no request.

Por outro lado, se eu uso: user = User.objects.get(id=self.initial_data["employee"]), dá certo!

O que acontece após o serializer.is_valid(), eu não deveria manter a mesma informação do body tanto no validated_data quanto no self.initial_data?

Não manjo muito mas parece que tá faltando um ".id" no final de user = User.objects.get(id=validated_data["employee"]) que aparece anteriormente.

Depois de um período, pesquisa e debug em situações parecidas, queria deixar registrado aqui o que aparentemente acontece.

A diferença chave entre validated_data e initial_data é:

initial_data: Contém os dados brutos que foram enviados para o serializer. Esses dados ainda não foram validados nem transformados.

validated_data: Contém os dados após terem sido validados. Os campos que representam relações com outros modelos, como ForeignKey, são convertidos em instâncias do modelo correspondente se a validação for bem-sucedida.

No meu caso,"employee": 1 é enviado como parte do JSON. Quando o serializer é validado:

self.initial_data["employee"] contém o valor bruto 1. validated_data["employee"] deve conter uma instância do modelo User correspondente ao id 1 uma vez que o campo employee é um campo de relação em Models.

Como validated_data["employee"] está retornando um objeto do tipo User, isso significa que o DRF conseguiu resolver a referência id para um objeto User durante a validação.


Quando você usa o PrimaryKeyRelatedField em um serializer do Django Rest Framework, o comportamento padrão é que, após a validação, o validated_data contém a instância do objeto referenciado, não apenas o ID. Isso ocorre porque o DRF resolve a referência de chave primária para o objeto correspondente durante a validação para garantir que o ID fornecido aponte para um objeto válido.

No entanto, se o objetivo é ter apenas o ID no validated_data após a validação, eu teria que personalizar o comportamento do serializer. Por padrão, tanto a abordagem explícita (definindo PrimaryKeyRelatedField) quanto a implícita (deixando o DRF inferir o campo com base no modelo) resultarão em validated_data contendo o objeto inteiro.

Para manter apenas o ID em validated_data, seria necessário uma abordagem personalizada, talvez sobrescrevendo o método to_internal_value ou create/update no serializer para manipular validated_data de forma que apenas o ID seja armazenado.