Pruk Ambavamata Pruk Ambavamata - 3 months ago 12
JSON Question

What's the best way to serialize more than one model to json in Django 1.6?

I have 3 models show as below.

class DocumentClass(models.Model):
text = models.CharField(max_length=100)


class DocumentGroup(models.Model):
text = models.CharField(max_length=100)
documentclass = models.ForeignKey(DocumentClass)


class DocumentType(models.Model):
text = models.CharField(max_length=100)
documentgroup = models.ForeignKey(DocumentGroup)


And my goal is something like this:

[
{
'pk': 1,
'model': 'DocumentClass',
'fields':{
'text':'DocumentClass1',
'documentgroup':
[
{
'pk': 1,
'model': 'DocumentGroup'
'field':
{
'text':'DocumentGroup1'
}
}
]
}
},
{
'pk': 2,
'model': 'DocumentClass',
'fields':{
'text':'DocumentClass2'
}
}
]


I usually serialize a model by

jsonstr = serializers.serialize("json", DocumentType.objects.all())


But for my goal. I have no idea.
As the title. What is the best way to do that?

Edit:
The relation of above models look like:

DocumentClass1
|-DocumentGroup1
| |-DocumentType1
| |-DocumentType2
| |-...
|-DocumentGroup2
| |-...
DocumentClass2
|-DocumentGroup...
| |-DocumentType...

Answer

If The Models Are Related

This will require some more customized serialization, for which you will have to use Django Rest Framework's serializers.

Try subclassing ModelSerializer:

class DocumentTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = DocumentType


class DocumentGroupSerializer(serializers.ModelSerializer):
    types = DocumentTypeSerializer(many=True)

    class Meta:
        model = DocumentGroup


class DocumentClassSerializer(serializers.ModelSerializer):
    groups = DocumentGroupSerializer(many=True)

    class Meta:
        model = DocumentClass


queryset = DocumentClass.objects.all()
serializer = DocumentClassSerializer(queryset, many=True)
json = JSONRenderer().render(serializer.data)

If The Models Are Not Related

According to the Django docs, the 2nd argument to serialize() can be "any iterator that yields Django model instances".

Now you'll need to pass your 3 kinds of instances as an iterator. It seems like Python's itertools.chain is the preferred method, as voted here.

So your call would look something like:

instances = list(chain(DocumentClass.objects.all(), DocumentGroup.objects.all(), DocumentType.objects.all())
jsonstr = serializers.serialize("json", instances)
Comments