Registered User
Registered User

Reputation: 2299

Django: How do I return data from db along with the foreign key entities to the user as JSON?

I have two models as such,

class Foo(models.Model):
    name = models.CharField(max_length=100, unique=True)
    city = models.CharField(max_length= 50)
    ....

and

class Bar(models.Model):
    Foo = models.ManyToManyField(Foo)
    name = models.CharField(max_length=20, unique=True)

I have a view that returns Foo objects as JSON,

def list_by_city(request, city):
    foo_list = Foo.objects.filter(city=city).values()
    return JsonResponse({"Foo": list(foo_list)})

But this returns only the attributes from Foo. I want to add the attributes from Bar as well, which are related to Foo. How do I do that?

EDIT: The resulting JSON should be somewhat like,

{
   "Foo":[
      {
         "id":1,
         "name":"A",
         "city":"B",
         "Bars":[
            {
               "name":"A"
            },
            {
               "name":"B"
            }
         ]
      },
      {
         "id":2,
         "name":"C",
         "city":"B",
         "Bars":[
            {
               "name":"D"
            }
         ]
      }
   ]
}

Upvotes: 1

Views: 65

Answers (2)

Yannic Hamann
Yannic Hamann

Reputation: 5215

You could use just the serialization component of Django Rest Framework. It provides a declarative serializer that is more flexible than the one in Django.

models.py:

class Bar(models.Model):
    foo = models.ManyToManyField(Foo, related_name='bars')
    name = models.CharField(max_length=20, unique=True)

serializers.py:

from rest_framework import serializers
from .models import Foo, Bar


class BarSerializer(serializers.ModelSerializer):
    class Meta:
        model = Bar
        fields = ('name',)


class FooSerializer(serializers.ModelSerializer):
    bars = BarSerializer(many=True, read_only=True)

    class Meta:
        model = Foo
        fields = ('name', 'city', 'bars')

Which results in:

>>> s = FooSerializer(my_foo_object)
>>> s.data
{'bars': [OrderedDict([('name', 'B')]), OrderedDict([('name', 'A')])], 'city': 'Bangkok', 'name': 'Foo'}

To serialize a queryset or list of objects you can do FooSerializer(Foo.objects.all(), many=True).

Upvotes: 1

James Burgess
James Burgess

Reputation: 497

You can add another item to the dictionary in the view with this:

 def list_by_city(request, city):
        response_data = {}
        response_data['foo_list'] = Foo.objects.filter(city=city).values()
        response_data['bar_list'] = Foo.objects.filter(country=country).values()
        return JsonResponse(json.dumps(response_data))

Upvotes: 0

Related Questions