Home > Software engineering >  How to get list as a value from another model of a serializer key's value in DRF serializer?
How to get list as a value from another model of a serializer key's value in DRF serializer?

Time:09-01

Models:

class SellerHub(BaseModel):
    name = models.CharField(blank=False, max_length=255)
    address = models.TextField(
        blank=True,
    )
    status = models.BooleanField(default=True)
    contact_person = models.CharField(blank=False, max_length=255)
    hub_type = models.ForeignKey(SellerHubType, on_delete=models.CASCADE)
    latitude = models.DecimalField(
        max_digits=22, decimal_places=16, blank=True, null=True
    )
    longitude = models.DecimalField(
        max_digits=22, decimal_places=16, blank=True, null=True
    )
    image = models.ImageField(
        default="default_images/default_seller_hub.png",
        upload_to=seller_hub_image_path,
    )
    status = models.BooleanField(default=True)

    class Meta:
        app_label = "seller_hub"

    def __str__(self):
        return self.name


class SellerHubPhone(BaseModel):
    seller_hub = models.ForeignKey(SellerHub, on_delete=models.CASCADE)
    phone = PhoneNumberField(blank=False, max_length=255)
    status = models.BooleanField(default=True)

    def __str__(self):
        return f"{str(self.phone)} for {self.seller_hub.name}"


Serializers:

from rest_framework import serializers
from seller_hub.selectors import seller_phone
from phonenumber_field.serializerfields import PhoneNumberField


class SellerHubPhoneSerializer(serializers.Serializer):
    phone = PhoneNumberField()


class SellerHubSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    name = serializers.CharField(max_length=255)
    address = serializers.CharField()
    image = serializers.ImageField()
    phone = serializers.SerializerMethodField("get_phone")

    def get_phone(self, obj):
        hub_phone = seller_phone(obj)  # Returns a queryset of SellerHubPhone objects
        print("Phone: ", hub_phone)
        serializer = SellerHubPhoneSerializer(hub_phone, many=True)
        return serializer.data

This is my current output:

"data": [
    {
        "id": 1,
        "name": "Test Seller Hub",
        "address": "Test seller Address",
        "image": "http://127.0.0.1:8000/media/default_images/default_seller_hub.png",
        "phone": [
            {
                "phone": " 8801777777777"
            },
            {
                "phone": " 491783379222"
            }
        ]
    }
]

Expected Output:

"data": [
    {
        "id": 1,
        "name": "Test Seller Hub",
        "address": "Test seller Address",
        "image": "http://127.0.0.1:8000/media/default_images/default_seller_hub.png",
        "phone": [
             " 8801777777777",
             " 491783379222"
        ]
    }
]

Here SellerHub might have multiple phone numbers, so I am using SellerHubPhone and adding the SellerHub as a foreign key. I want to get all the phone numbers of a SellerHub using The SellerHubPhone Model object and the output should look like the expected output JSON. How to get the expected output by changing the serializer?

CodePudding user response:

You can return a list of phone, I am not sure but this can help you

def get_phone(self, obj):
    hub_phone = seller_phone(obj)  # Returns a queryset of SellerHubPhone objects
    print("Phone: ", hub_phone)
    serializer = SellerHubPhoneSerializer(hub_phone, many=True)
    return [x.phone for x in serializer.data]

CodePudding user response:

After getting the idea from @mecaTheclau answer I tried this solution. This one worked for me. As the returning objects were OrderedDict, I had to change his solution.

  def get_phone(self, obj):
        hub_phone = seller_phone(obj)  # Returns a queryset of SellerHubPhone objects
        print("Phone: ", hub_phone)
        serializer = SellerHubPhoneSerializer(hub_phone, many=True)
        return [next(iter(x.values())) for x in serializer.data]
  • Related