Cephlin Cephlin - 5 months ago 39
JSON Question

Serialize model objects into a JSON dict using django-rest-framework

So if I have the following model class in Django:

class Person(models.Model):
name = models.CharField(max_length=250)
is_active = models.BooleanField(default=True)

address_line1 = models.CharField(max_length=100, blank=True, null=True)
address_line2 = models.CharField(max_length=100, blank=True, null=True)
town = models.CharField(max_length=100, blank=True, null=True)
county = models.CharField(max_length=100, blank=True, null=True)
post_code = models.CharField(max_length=100, blank=True, null=True)


and my goal is to serialize it into the following JSON:

{
"name": "Joe Bloggs",
"is_active": true,
"contact": {
"address1": "Bloggs House"
"address2": "1 Bloggs Lane",
"city": "Bloggs Town",
"county": "Bloggs Town",
"zip": "BL0 GG5",
"country": "UK"
}
}


I tried the following, but it didn't work and I'm pretty sure that's not how the serializers.ListField is meant to work (I think it's meant to be for a list of the same thing):

class MailChimpListSerializer(serializers.ModelSerializer):
class Meta:
model = Person

contact = serializers.DictField(
address1=serializers.CharField(source='address_line1'),
address2=serializers.CharField(source='address_line2'),
city=serializers.CharField(source='town'),
state=serializers.CharField(source='town', read_only=True),
zip=serializers.CharField(source='post_code'),
country=serializers.SerializerMethodField()
)

permission_reminder = serializers.SerializerMethodField()

campaign_defaults = serializers.DictField(
from_name=serializers.CharField(source='name'),
from_email=serializers.CharField(source='primary_contact_email'),
subject=serializers.CharField(),
language=serializers.CharField()
)

email_type_option = serializers.SerializerMethodField()

fields = ('name', 'contact', 'permission_reminder',
'campaign_defaults', 'email_type_option')


How do I create the contact JSON list with the address etc in it?

Answer

What you want is a DictField not a ListField, the key contact in your desired JSON output is an object (dict in Python), not a list:

contact = serializers.DictField(
            address1=serializers.CharField(source='address_line1'),
            address2=serializers.CharField(source='address_line2'),
            ...
)

Here's another way that is more manual:

class MySerializer(serializers.ModelSerializer):
    contact = serializers.SerializerMethodField()
    def get_contact(self, obj):
        return dict(
            address1=obj.address1, # As long as the fields are auto serializable to JSON
            some_field=SomeSerializer(obj.some_field).data,
        )
Comments