Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serialize django models with reverse One-To-One fields to JSON

Lets say I have the following two django (1.3) models

from django.db import models
class Patient(models.Model):
    name =  models.CharField('Name', max_length=50)

class Address(models.Model):
    town = models.CharField('Town/Village', max_length=50)
    patient = models.OneToOneField(Patient, related_name='address')

Now when i try to serialize a Patient model instance to JSON using django's serializers, the resulting JSON string does'nt have the address details with it (it's unable to traverse through the reverse direction of One-to-one relation)

This happens event if I use select_related('address') to populate the address object into the cache. i.e.

from django.core import serializers
>>> print serializers.serialize('json',[Patient.objects.select_related('address').get(id=1)])

Is there are way I can get around this problem?

like image 797
Deepan Avatar asked Nov 14 '22 22:11

Deepan


1 Answers

This problem came up in the project I am currently developing. Here is the solution we were going to use before we decided to just extend the Django serializer ourselves. This should work just fine for your needs though.

To solve the problem with out getting your hands dirty I would recommend wadofstuff's Django Full Serializers.

After getting it setup using the wiki solving your example would look something like this:

You need to add a method to your model which returns a python representation of the QuerySet.

from django.db import models
from django.core import serializers
class Patient(models.Model):
    name =  models.CharField('Name', max_length=50)

    def extra_address(self):
        return serializers.serialize('python', self.address.all())

class Address(models.Model):
    town = models.CharField('Town/Village', max_length=50)
    patient = models.OneToOneField(Patient, related_name='address')

Then you can add the method to the list of extras taken by the more robust serializer.

from django.core import serializers
print serializers.serialize('json', Patient.objects.all(), extras=('extra_address',))

An extras key will be added to the dictionary and will have whatever extra pieces of information you needed in it.

like image 184
Dan Avatar answered Dec 07 '22 22:12

Dan