Django Rest Framework嵌套序列化程序不显示相关数据

Lan*_*don 11 python django django-rest-framework

我有一个使用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
Run Code Online (Sandbox Code Playgroud)

当我在Django的Shell中查看序列化器关系时,它正确地显示了关系:

PlanSerializer():
name = CharField(max_length='100')
group = GroupSerializer(many=True, read_only=True):
    name = CharField(max_length='50')
    weight = IntegerField()
Run Code Online (Sandbox Code Playgroud)

我最终通过cURL回来的是:

[
    {
        name: Test Plan
    }
]
Run Code Online (Sandbox Code Playgroud)

我希望得到的是:

[
    {
        name: Test Plan,
        group: [
                {
                    name: Test Group,
                    weight: 1
                }
        ] 
    }
]
Run Code Online (Sandbox Code Playgroud)

没有嵌套数据通过.因为我在这里没有正确设置,我很遗憾.谁能指出我正确的方向?

Tod*_*dor 17

问题来自你queryset:queryset = Plan.objects.all().此中没有任何项queryset具有.group属性,这就是结果为空的原因.默认情况下,Django创建一个plan被调用的ForeignKey 的反向关系group_set(除非你不通过它重命名related_name)(这意味着它的每个planqueryset都有一个group_set属性,它是一个包含所有这些组的查询集plan).您可以使用此属性以获得正确的序列化.这意味着改变:

class PlanSerializer(serializers.ModelSerializer):
    group_set = GroupSerializer(many=True, read_only=True)

    class Meta:
        model = Plan
        fields = ('name', 'group_set')
Run Code Online (Sandbox Code Playgroud)

如果你真的想坚持group (顺便说一下,这是一个非常糟糕的名字列表).你可以prefetch_related像这样破解它:

queryset = Plan.objects.prefetch_related('group_set', to_attr='group')
Run Code Online (Sandbox Code Playgroud)

这样每个plan项目都有一个group属性 - queryset包含所有这些组plan.

  • 您可以在通过“ related_name”定义FK时更改默认的xxx_set表示法,例如“ plan = models.ForeignKey('plan',related_name ='groups')”。现在您将没有`group_set`属性,而是拥有`groups`属性。 (2认同)