Adrian Debbeler
Adrian Debbeler

Reputation: 33

Django: Serialize queryset and include one-to-many relationship children

I want to serialize a queryset of an object which has a one-to-many relationship to another model. I want to include the related objects in my json output.

Example:

class Book(models.Model):
    title = models.CharField()
    author = models.ForeignKey('Author')

class Author(models.Model):
    name = models.CharField()

view.py:

serializers.serialize('json', Author.objects.all()) #does not include the book objects

I am pretty sure there is an easy solution, but so far I was not able to figure out how to do it. Thanks for your help!

Upvotes: 3

Views: 3526

Answers (3)

gabmichelet
gabmichelet

Reputation: 63

Last year, I needed something like that, working with Flask. I used this thread. It would give you something like this :

class Book(models.Model):
    title = models.CharField()
    author = models.ForeignKey('Author')

    @property
    def serialize(self):
        return {
            'title'    : self.title,
            'author'   : self.author.serialize
        }

class Author(models.Model):
    name = models.CharField()

    @property
    def serialize(self):
        return {
            'name'    : self.name
        }

    @property
    def serialize_books(self):
        return [ book.serialize for book in self.book_set.all() ]

Edit : this answer is pretty the same than @sneawo's one. The only difference is that you can chain serialize methods.

Upvotes: 1

sneawo
sneawo

Reputation: 3641

You can't do it from default django serializer, because the Author model has not books field. You can achieve it by creating your own serializer or manually build your data and pass it to simplejson.dumps()

Update

For example:

class Author(models.Model):
    ...
    def get_json(self):
        return {
            'id': self.id, 
            'name': self.name,
            'books': [{'id': b.id, 'title': b.title} for b in self.book_set.all()] }

from django.utils import simplejson
simplejson.dumps([a.get_json() for a in Author.objects.all()])

Upvotes: 6

pemistahl
pemistahl

Reputation: 9584

Do you want to export your JSON data to a file? If so, you can also use the management command dumpdata:

python manage.py dumpdata your_app.Book your_app.Author > my_models.json

This would save the data of both models into the file my_models.json.

Instead, if you want to serialize your data to be used for AJAX requests or the like, you can wrap your model data in a dictionary. Do something like this in your view:

# The querysets must be wrapped in list()
# otherwise they can't be serialized as JSON objects
response = {  
    'authors': list(Author.objects.all()),
    'books': list(Book.objects.all())
}

return HttpResponse(simplejson.dumps(response), mimetype='application/json')

Upvotes: 1

Related Questions