[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 id
está 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.