Search code examples
djangodjango-modelsdjango-rest-frameworkdjango-serializer

get the related records in a serializer - django


I am trying to obtain in a query the data of a client and the contacts he has registered I tried to do it in the following way but it did not work.

class ClientReadOnlySerializer(serializers.ModelSerializer):
    clientcontacts = ClientContactSerializer(many=True, read_only=True)
    class Meta:
        model  = Client
        fields = "__all__"

Is there any way to make this relationship nested?

these are my models

clients model
# Relations
from apps.misc.models import City, TypeIdentity, TypeCLient, CIIU
from apps.clients.api.models.broker.index import Broker
from apps.authentication.models import User


class Client(models.Model):
    id              = models.CharField(max_length=255, unique=True,primary_key=True, editable=False)
    type_client     = models.ForeignKey(TypeCLient, on_delete=models.CASCADE, blank=True)
    type_identity   = models.ForeignKey(TypeIdentity, on_delete=models.CASCADE, blank=True)
    document_number = models.CharField(max_length=255, blank=True, unique=True)
    first_name      = models.CharField(max_length=255, blank=True, null=True)
    last_name       = models.CharField(max_length=255, blank=True, null=True)
    social_reason   = models.CharField(max_length=255, blank=True, null=True)
    city            = models.ForeignKey(City, on_delete=models.CASCADE, blank=True)
    address         = models.CharField(max_length=255, blank=True)
    email           = models.CharField(max_length=255, blank=True, unique=True)
    phone_number    = models.CharField(max_length=255, blank=True, unique=True)
    ciiu            = models.ForeignKey(CIIU, on_delete=models.CASCADE, blank=True)
    broker          = models.ForeignKey(Broker, on_delete=models.CASCADE, blank=True)
    user            = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
    income          = models.SmallIntegerField(blank=True, default=0)
    state           = models.BooleanField(default=True)
    created_at      = models.DateTimeField(auto_now_add=True)
    updated_at      = models.DateTimeField(null=True, default=None)

client contacts model

# Relations
from apps.clients.api.models.index import Client


class ClientContact(models.Model):
    id           = models.CharField(max_length=255, primary_key=True, unique=True, editable=False)
    client       = models.ForeignKey(Client, on_delete=models.CASCADE)
    first_name   = models.CharField(max_length=255)
    last_name    = models.CharField(max_length=255)
    phone_number = models.CharField(max_length=255)
    state        = models.BooleanField(default=True)
    created_at   = models.DateTimeField(auto_now_add=True)
    updated_at   = models.DateTimeField(null=True, blank=True, default=None)

Solution

  • after some research I came up with a solution that doesn't seem very practical, what I did was to create a method in the serializer that queries the client's contacts as follows

    class ClientReadOnlySerializer(serializers.ModelSerializer):
        contacts = serializers.SerializerMethodField(method_name='get_contacts')
        class Meta:
            model  = Client
            fields = "__all__"
            extra_fields = ['contacts']
    
        
        def get_contacts(self, obj):
            contacts   = ClientContact.objects.filter(client=obj)
            serializer = ClientContactSerializer(contacts, many=True)
            return serializer.data
    

    using the model and the serializer of the contact model I made a query which I added in an extra field of the customer serializer, if someone knows how to make this process more optimal please reply.