Django Rest Framework 嵌套序列化程序不显示相关数据
Django Rest Framework nested serializer not showing related data
我使用 Django Rest Framework 进行了基本设置。我有两个模型和一个嵌套的序列化程序设置:
# 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
当我在 Django 的 Shell 中查看序列化器关系时,它正确显示了关系:
PlanSerializer():
name = CharField(max_length='100')
group = GroupSerializer(many=True, read_only=True):
name = CharField(max_length='50')
weight = IntegerField()
我最终通过 cURL 得到的结果是:
[
{
name: Test Plan
}
]
我期望得到的是:
[
{
name: Test Plan,
group: [
{
name: Test Group,
weight: 1
}
]
}
]
没有嵌套数据通过。我对这里没有正确设置的东西感到茫然。谁能指出我正确的方向?
问题来自您的queryset
:queryset = Plan.objects.all()
。此 queryset
中的 None 项具有 .group
属性,这就是您的结果为空的原因。默认情况下,Django 创建一个名为 group_set
的 plan
外键的反向关系(除非你不通过 related_name
重命名它)(这意味着每个 plan
queryset
中的项目有一个 group_set
属性,它是一个包含此 plan
) 的所有组的查询集。您可以使用此属性以获得正确的序列化。这意味着改变:
class PlanSerializer(serializers.ModelSerializer):
group_set = GroupSerializer(many=True, read_only=True)
class Meta:
model = Plan
fields = ('name', 'group_set')
如果你真的想坚持使用 group
(顺便说一句,这对于组列表来说是一个非常糟糕的名称)。你可以像这样用 prefetch_related
破解它:
queryset = Plan.objects.prefetch_related('group_set', to_attr='group')
这样每个 plan
项目都会有一个 group
属性 - 一个 queryset
包含这个 plan
.
的所有组
永远不要忘记为外键提供相关名称。例如
在模型中
plan = modles.ForeignKey(Plan, related_name="plan")
在序列化程序中
plan = PlanSerializers(many = True, read_only = True)
我使用 Django Rest Framework 进行了基本设置。我有两个模型和一个嵌套的序列化程序设置:
# 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
当我在 Django 的 Shell 中查看序列化器关系时,它正确显示了关系:
PlanSerializer():
name = CharField(max_length='100')
group = GroupSerializer(many=True, read_only=True):
name = CharField(max_length='50')
weight = IntegerField()
我最终通过 cURL 得到的结果是:
[
{
name: Test Plan
}
]
我期望得到的是:
[
{
name: Test Plan,
group: [
{
name: Test Group,
weight: 1
}
]
}
]
没有嵌套数据通过。我对这里没有正确设置的东西感到茫然。谁能指出我正确的方向?
问题来自您的queryset
:queryset = Plan.objects.all()
。此 queryset
中的 None 项具有 .group
属性,这就是您的结果为空的原因。默认情况下,Django 创建一个名为 group_set
的 plan
外键的反向关系(除非你不通过 related_name
重命名它)(这意味着每个 plan
queryset
中的项目有一个 group_set
属性,它是一个包含此 plan
) 的所有组的查询集。您可以使用此属性以获得正确的序列化。这意味着改变:
class PlanSerializer(serializers.ModelSerializer):
group_set = GroupSerializer(many=True, read_only=True)
class Meta:
model = Plan
fields = ('name', 'group_set')
如果你真的想坚持使用 group
(顺便说一句,这对于组列表来说是一个非常糟糕的名称)。你可以像这样用 prefetch_related
破解它:
queryset = Plan.objects.prefetch_related('group_set', to_attr='group')
这样每个 plan
项目都会有一个 group
属性 - 一个 queryset
包含这个 plan
.
永远不要忘记为外键提供相关名称。例如
在模型中
plan = modles.ForeignKey(Plan, related_name="plan")
在序列化程序中
plan = PlanSerializers(many = True, read_only = True)