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.
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
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']