0

I have a serializer which looks like this:

class ListingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Listing
        fields = '__all__'

My Listing model have some field: name, price, description, etc.., street_address, postal_code, city, etc...

I would like my serializer to return an object like this:

{
    "name": "Prestige",
    "price": 12,
    "description": "lorem ipsum",
    "address": {
        "street": "123 Main St",
        "city": "New York",
        "state": "NY",
        "zip": "10001"
    },
    ...
}

instead of the basic:

{
    "name": "Prestige",
    "price": 12,
    "description": "lorem ipsum",
    "street": "123 Main St",
    "city": "New York",
    "state": "NY",
    "zip": "10001"
    ...
}

What I want is encapsulate all "address" field into an "address" object in my response.

BoumTAC
  • 3,531
  • 6
  • 32
  • 44
  • I hope this [SO post](https://stackoverflow.com/questions/29950956/drf-simple-foreign-key-assignment-with-nested-serializers/52246232) will help – JPG Feb 26 '23 at 15:40

1 Answers1

1

First option is to override .to_representation on your serializer:

serializers.py

class ListingSerializer(serializers.ModelSerializer):
    class Meta:
        model = Listing
        fields = '__all__'

    def to_representation(self, instance):
        representation = super().to_representation(instance)
        address = {}
        address['street'] = representation.pop('street')
        address['city'] = representation.pop('city')
        address['state'] = representation.pop('state')
        address['zip'] = representation.pop('zip')

        representation['address'] = address
        return representation

Alternatively

If it is possible to change your models, maybe the better option is to add an Address and associate it with Listing:

models.py

class Address(models.Model):
    street = models.CharField(max_length=100)
    city =models.CharField(max_length=20)
    state = models.CharField(max_length=5)
    zip = models.CharField(max_length=15)

class Listing(models.Model):
    name = models.CharField(max_length=255)
    price = models.IntegerField()
    description = models.CharField(max_length=255)
    address = models.ForeignKey(Address, on_delete=models.DO_NOTHING, related_name='listings')

serializers.py

class AddressSerializer(serializers.ModelSerializer):
    class Meta:
        model = Address
        exclude = ['id']

class ListingSerializer(serializers.ModelSerializer):
    address = AddressSerializer()

    class Meta:
        model = Listing
        fields = ['name', 'price', 'description', 'address']
Niko
  • 3,012
  • 2
  • 8
  • 14