Myrzabek
Myrzabek

Reputation: 57

how to get specific field in serialiser with related_name by Django rest

i have model named ContactPhone and in the model link to Lead model with field lead_id and ralated_name phones

class ContactPhone(models.Model):
    phone_number = PhoneNumberField(blank=True, default='')
    phone_type = models.CharField(
        max_length=100,
        blank=True,
        choices=ContactPhoneInterface.phone_number_types,
        default=PhoneNumbers.mobile.name
    )
    contact_id = models.ForeignKey(
        Contact,
        on_delete=models.CASCADE,
        null=True,
        related_name='phones_c'
    )
    lead_id = models.ForeignKey(
        Lead,
        on_delete=models.CASCADE,
        null=True,
        related_name='phones'
    )

by this serilizer class i got id of ContactPhone table, but i need got phone_number field in ContactPhone.

class LeadListSerializer(serializers.ModelSerializer):

    class Meta:
        model = Lead
        fields = (
            'id',
            'full_name',
            'responsible_id',
            'phones',
            'emails',
        )

tried different options to solve this problem but it doesn't help. In the screenshot you can see response of this moment, id of ContactPhone

enter image description here

Upvotes: 1

Views: 554

Answers (1)

Iain Shelvington
Iain Shelvington

Reputation: 32244

If you want to return a list of specific fields from a related model you can use a serializers.SlugRelatedField

class LeadListSerializer(serializers.ModelSerializer):

    phones = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='phone_number'
    )

    class Meta:
        model = Lead
        fields = (
            'id',
            'full_name',
            'responsible_id',
            'phones',
            'emails',
        )

EDIT: The ContactPhone.phone_number field is not serializable

One option is to set the __str__ method of the ContactPhone model to return the phone number and use a StringRelatedField

class ContactPhone(models.Model):
    ...

    def __str__(self):
        return str(self.phone_number)


class LeadListSerializer(serializers.ModelSerializer):

    phones = serializers.StringRelatedField(
        many=True,
        read_only=True,
    )

    class Meta:
        model = Lead
        fields = (
            'id',
            'full_name',
            'responsible_id',
            'phones',
            'emails',
        )

Or adding a property that returns the string of phone_number to the ContactPhone model and using that in a SlugRelatedField is potential option

class ContactPhone(models.Model):
    ...

    @property
    def phone_number_str(self):
        return str(self.phone_number)


class LeadListSerializer(serializers.ModelSerializer):

    phones = serializers.SlugRelatedField(
        many=True,
        read_only=True,
        slug_field='phone_number_str'
    )

    class Meta:
        model = Lead
        fields = (
            'id',
            'full_name',
            'responsible_id',
            'phones',
            'emails',
        )

Upvotes: 1

Related Questions