DRF/Django - How to send an attribute value instead of sending a JSON object

Asked

Viewed 15 times

-1

Hello, I have an object related to several others, however when I send the JSON, either goes the ID of the related objective or I serializo it and goes the whole object, I would like to send only one attribute of this related object.

How is returning the object:

    "id": 2,
    "tipoManifestacao": {
        "id": 2,
        "tipoManifestacao": "Sugestão",
        "created_at": "2021-07-14T20:34:00.176140-03:00"
    },
    "modoResposta": {
        "id": 2,
        "modoResposta": "Por Telefone",
        "created_at": "2021-07-14T20:34:29.092794-03:00"
    },
    "orgao": {
        "id": 2,
        "orgao": "HOSPITAL DE IGARASSU",
        "contato": "81818118",
        "created_at": "2021-07-14T20:33:44.335234-03:00",
        "setor": null
    },
    "protocolo": "20210718002",
    "descricao": "string",
    "created_at": "2021-07-18T17:53:12.902620-03:00"
}```

como eu gostaria que retornasse: 

{
    "id": 2,
    "tipoManifestacao": "Sugestão",
    "modoResposta": "Por Telefone",
    "orgao": "HOSPITAL DE IGARASSU",
    "protocolo": "20210718002",
    "descricao": "string",
    "created_at": "2021-07-18T17:53:12.902620-03:00"
}

meu views.py

'''class ManifestacaoViewSet(ModelViewSet):
    serializer_class = ManifestacaoSerializer
    filter_backends = [SearchFilter]

    permission_classes = [permissions.IsAuthenticated, ]
    search_fields = ['protocolo', 'pessoa']

    def get_queryset(self):
        return Manifestacao.objects.filter()

    def list(self, request, *args, **kwargs):
        return super(ManifestacaoViewSet, self).list(request, *args, **kwargs)

    def create(self, request, *args, **kwargs):
        #try:
        data = datetime.datetime.now()
        ultima_manifestacao = Manifestacao.objects.last()

        if ultima_manifestacao:
            ultimo_protocolo = ultima_manifestacao.protocolo
            ultima_data = ultimo_protocolo[:8]
            ultimo_numero = ultimo_protocolo[-3:]
        else:
            ultima_data = '00000000'
            ultimo_numero = '000'

        nova_data = str(data.year) + str(data.month).zfill(2) + str(data.day).zfill(2)

        if int(ultima_data) == int(nova_data):
            novo_numero = int(ultimo_numero) + 1
        else:
            novo_numero = '001'

        novo_protocolo = nova_data + str(novo_numero).zfill(3)
        request.data['protocolo'] = novo_protocolo
        user = request.user
        request.data['funcionario'] = user.pk
        return super(ManifestacaoViewSet, self).create(request, *args, **kwargs)

    def retrieve(self, request, *args, **kwargs):
        return super(ManifestacaoViewSet, self).retrieve(request, *args, **kwargs)

    def destroy(self, request, *args, **kwargs):
        return super(ManifestacaoViewSet, self).destroy(request, *args, **kwargs)

    def update(self, request, *args, **kwargs):
        user = request.user
        request.data['funcionario'] = user.pk
        print("passou por update views")
        serializer = self.serializer_class(data=request.data)
        serializer.is_valid(raise_exception=True)
        return Response(serializer.data, status=status.HTTP_200_OK)

    def partial_update(self, request, *args, **kwargs):
        return super(ManifestacaoViewSet, self).partial_update(request, *args, **kwargs)'''


meu serializers.py

class ManifestacaoSerializer(ModelSerializer):
    localDoFato = LocalDoFatoSerializer(required=False, allow_null=True)
    envolvidos = EnvolvidosSerializer(required=False, allow_null=True)
    assunto = AssuntoSerializer()
    tipoManifestacao = TipoManifestacaoSerializer()
    modoResposta = ModoRespostaSerializer()
    orgao = OrgaoSerializer()
    CanalDeEntrada = CanalDeEntradaSerializer()
    pessoa = PessoaSerializer()
    funcionario = UserSerializer()


    class Meta:
        model = Manifestacao
        fields = '__all__'

    def create(self, validated_data):
        envolvidos_data = validated_data.pop('envolvidos')
        local_data = validated_data.pop('localDoFato')

        if envolvidos_data:
            envolvidos = Envolvidos.objects.create(**envolvidos_data)
        if local_data:
            localDoFato = LocalDoFato.objects.create(**local_data)

        if local_data and envolvidos_data:
            manifestacao = Manifestacao.objects.create(envolvidos=envolvidos, localDoFato=localDoFato, **validated_data)
        elif local_data and not envolvidos_data:
            manifestacao = Manifestacao.objects.create(localDoFato=localDoFato, **validated_data)
        elif envolvidos_data and not local_data:
            manifestacao = Manifestacao.objects.create(envolvidos=envolvidos,**validated_data)
        else:
            manifestacao = Manifestacao.objects.create(**validated_data)
        return manifestacao

    def update(self, instance, validated_data):
        manifestacao = Manifestacao.objects.get(id=self.data['id'])
        envolvidos_data = validated_data.pop('envolvidos')
        localDoFato_data = validated_data.pop('localDoFato')
        if envolvidos_data:
            if manifestacao.envolvidos:
                id_env = manifestacao.envolvidos.id
                envolvidos = Envolvidos.objects.get(id=id_env)
                for key in envolvidos_data:
                    setattr(envolvidos, key, envolvidos_data.get(key, getattr(envolvidos, key)))
                    envolvidos.save()
            else:
                envolvidos = Envolvidos.objects.create(**envolvidos_data)
                manifestacao.envolvidos = envolvidos
                manifestacao.save()

        if localDoFato_data:
            if manifestacao.localDoFato:
                id_soc = manifestacao.localDoFato.id
                localDoFato = LocalDoFato.objects.get(id=id_soc)
                for key in localDoFato_data:
                    setattr(localDoFato, key, localDoFato_data.get(key, getattr(localDoFato, key)))
                    localDoFato.save()
            else:
                localDoFato = LocalDoFato.objects.create(**localDoFato_data)
                manifestacao.localDoFato = localDoFato
                manifestacao.save()
        print("passou por update Serializers")
        mensagem = 'Atualizado com sucesso'
        return mensagem

2 answers

0

You can try to modify the behavior of your serializer. As you say that one documentation.

You specify the return __str__ of its related objects, and will retrieve only that information.

When accessing the link, see the first example, right after the sample templates.

0

You can use the attribute source of Fields of the Django Rest Framework to say where to find the data serialize will put on JSON.

Assuming you’re using a Modelserializer, your example would look something like:

class MeuSerializer(serializers.ModelSerializer):
    tipoManifestacao = serializers.CharField(source="tipoManifestacao.tipoManifestacao")
    modoResposta = serializers.CharField(source="modoResposta.modoResposta")
    orgao = serializers.CharField(source="orgao.orgao")

    class Meta:
        model = MeuModel
        fields = [
            "id",
            "tipoManifestacao",
            "modoResposta",
            "orgao",
            "protocolo",
            "descricao",
            "created_at",
        ]

Note that I don’t need to create Fields for the fields that are already correct, I only overwrite those that want to change the behavior.

What I did was tell DRF that instead of serializing the field as a "sub-serializer" it was so that this field was a string and where its value should be searched.

PS: I only informed the parameter source not to pollute the example but perhaps you want to add others, as read_only.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.