Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

serialize model object with related objects to JSON

I am having a Person model to store person details.

class Person(models.Model):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)    
    birthdate = models.DateField()

also i am having model PersonLogs to store person's activity logs.

class PersonLogs(models.Model):
    person = models.ForeignKey(Person)
    time = models.DateTimeField(auto_now_add=True)

I am using Django Serializer to return Person objects into JSON format as response.

from django.core import serializers
data = serializers.serialize("json", Person.objects.all())

Output :

{
    "model": "store.person",
    "fields": {
        "first_name": "Douglas",
        "last_name": "Adams",
        "birth_date": "1952-03-11",
    }
}

Now i want to return PersonLogs into response JSON.

Expected Output :

{
    "model": "store.person",
    "fields": {
        "first_name": "Douglas",
        "last_name": "Adams",
        "birth_date": "1952-03-11",
        "personlogs": [['2015-06-09 15:42:58.861540'], ['2014-06-09 15:42:58.861540'], [2013-06-09 15:42:58.861540]]
    }
}

I looked into official documentation but i did not get any help. link

like image 654
Prashant Gaur Avatar asked Jun 09 '15 10:06

Prashant Gaur


People also ask

What is serializing and Deserializing in Django?

Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.

Why do we serialize objects in Django?

Django's serialization framework provides a mechanism for “translating” Django models into other formats. Usually these other formats will be text-based and used for sending Django data over a wire, but it's possible for a serializer to handle any format (text-based or not).


2 Answers

It seems that you want to serialize Person with reverse ForeignKey relationship. Django's serializer doesn't support that. You'll have to use Django REST Framework, for e.g., as pointed out in comments by @DanielRoseman.

But if you can compromise, the following solution will work.

class PersonManager(models.Manager):
    def get_by_natural_key(self, first_name, last_name, birthdate):
        return self.get(first_name=first_name, last_name=last_name, birthdate=birthdate)

class Person(models.Model):
   objects = PersonManager()

   # other fields
   ...

Now, instead of serializing Person, you'll have to serialize PersonLogs, which will output this:

{
    "pk": 1,
    "model": "models.PersonLogs",
    "fields": {
        "time": "2015-06-09 15:42:58.861540",
        "person": ["Douglas", "Adams", "1952-03-11"]
    }
}
like image 94
xyres Avatar answered Oct 09 '22 10:10

xyres


You can use serialize template.

Give related name to PersonLogs

class PersonLogs(models.Model):
    person = models.ForeignKey(Person,related_name='logs')
    time = models.DateTimeField(auto_now_add=True)

Create serialize templates

logs_template = {
    'fields': [':local'],
}
person_template = {
    'fields' :[':local',':related'],
    'related':{
         'logs':logs_template,
    }
}

Serialize it with below function:

from preserialize.serialize import serialize
finaldata = serialize(data, **person_template)
like image 37
Jay Jayswal Avatar answered Oct 09 '22 11:10

Jay Jayswal