I have a basic setup using the Django Rest Framework. I have two models and a nested serializer setup:
# models.py
from django.db import models
class Plan(models.Model):
name = models.CharField(max_length='100')
def __unicode__(self):
return u'%s' % (self.name)
class Group(models.Model):
plan = models.ForeignKey('plan')
name = models.CharField(max_length='50')
weight = models.SmallIntegerField()
def __unicode__(self):
return u'%s - %s' % (self.name, self.plan.name)
# serializer.py
from plans.models import Plan, Group
from rest_framework import serializers
class GroupSerializer(serializers.ModelSerializer):
class Meta:
model = Group
fields = ('name', 'weight')
class PlanSerializer(serializers.ModelSerializer):
group = GroupSerializer(many=True, read_only=True)
class Meta:
model = Plan
fields = ('name', 'group')
# views.py
from rest_framework import viewsets
from plans.models import Plan
from plans.serializers import PlanSerializer
class PlanViewSet(viewsets.ModelViewSet):
queryset = Plan.objects.all()
serializer_class = PlanSerializer
When I view the serializers relationships in Django's Shell it shows the relationship correctly:
PlanSerializer():
name = CharField(max_length='100')
group = GroupSerializer(many=True, read_only=True):
name = CharField(max_length='50')
weight = IntegerField()
What I end up getting back via cURL is:
[
{
name: Test Plan
}
]
What I expect to get back is:
[
{
name: Test Plan,
group: [
{
name: Test Group,
weight: 1
}
]
}
]
There is no nested data coming through. I'm at a lose for what I've not setup correctly here. Can anyone point me in the correct direction?
Never forget to give related name for the foreign key. for eg
In models
plan = modles.ForeignKey(Plan, related_name="plan")
In Serializers
plan = PlanSerializers(many = True, read_only = True)
The problem comes from your queryset
: queryset = Plan.objects.all()
. None of the items in this queryset
has .group
attribute that's why your result is empty. By default Django creates a reverse relation of the plan
ForeignKey called group_set
(unless you don't rename it via related_name
) (this means that every plan
item in the queryset
have a group_set
attribute which is a queryset containing all the groups of this plan
). You can use this attribute in order to get a proper serialization. This means to change:
class PlanSerializer(serializers.ModelSerializer):
group_set = GroupSerializer(many=True, read_only=True)
class Meta:
model = Plan
fields = ('name', 'group_set')
If you really want to stick with group
(btw this is a very bad name for a list of groups). You can hack it with prefetch_related
like so:
queryset = Plan.objects.prefetch_related('group_set', to_attr='group')
this way every plan
item will have a group
attribute - a queryset
containing all the groups for this plan
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With