【问题标题】:Django REST Framework Serializer returning object instead of dataDjango REST Framework Serializer 返回对象而不是数据
【发布时间】:2017-02-02 23:21:15
【问题描述】:

我正在为我所居住的公寓编写一个简单的数据库,其中包含人员、单元、单元类型(家庭与停车位)和单元持有人(个人和一个人之间的多对多关系的连接表)的列表unit) - 在租用停车位时,一个人可以成为“家”单元类型的所有者。

这是我的模型:

class Person(models.Model):
    first_name = models.CharField(max_length=30, null=False)
    last_name = models.CharField(max_length=30, null=False)
    phone = models.CharField(max_length=20)
    email = models.EmailField(max_length=20)

class UnitType(models.Model):
    description = models.CharField(max_length=30)

class Unit(models.Model):
    unit_number = models.IntegerField(null=False, unique=True)
    unit_type = models.ForeignKey(UnitType, null=False)
    unitholders = models.ManyToManyField(Person, through='UnitHolder')

class UnitHolderType(models.Model):
    description = models.CharField(max_length=30)

class UnitHolder(models.Model):
    person = models.ForeignKey(Person)
    unit = models.ForeignKey(Unit)
    unitholder_type = models.ForeignKey(UnitHolderType)

这是我的看法:

class PersonViewSet(viewsets.ModelViewSet):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer

class UnitHolderTypeViewSet(viewsets.ModelViewSet):
    queryset = UnitHolderType.objects.all()
    serializer_class = UnitHolderTypeSerializer

class UnitViewSet(viewsets.ModelViewSet):
    queryset = Unit.objects.all()
    serializer_class = UnitSerializer

class UnitHolderViewSet(viewsets.ModelViewSet):
    queryset = UnitHolder.objects.all()
    serializer_class = UnitHolderSerializer

class UnitTypeViewSet(viewsets.ModelViewSet):
    queryset = UnitType.objects.all()
    serializer_class = UnitTypeSerializer

这是我的序列化器:

class UnitSerializer(serializers.ModelSerializer):
    unit_type = serializers.SlugRelatedField(
        queryset=UnitType.objects.all(), slug_field='description'
    )

    class Meta:
        model = Unit
        fields = ('unit_number', 'unit_type', 'unitholders')

class UnitTypeSerializer(serializers.ModelSerializer):

    class Meta:
        model = UnitType

class PersonSerializer(serializers.ModelSerializer):
    class Meta:
        model = Person

class UnitHolderSerializer(serializers.ModelSerializer):
    person = serializers.PrimaryKeyRelatedField(many=False, read_only=True)
    unit = serializers.PrimaryKeyRelatedField(many=False, read_only=True)

    class Meta:
        model = UnitHolder
        fields = ('person', 'unit', 'unitholder_type')

class UnitHolderTypeSerializer(serializers.ModelSerializer):
    class Meta:
        model = UnitHolderType

问题:

当我查询 /units 端点时,如下所示:

u = requests.get('http://localhost:8000/units').json()

我的回复是这样的:

[{'unit_type': 'Home', 'unit_number': 614, 'unitholders': [1]}]

我想要回来的是这样的:

[
    {
        'unit_type': 'Home', 
        'unit_number': 614, 
        'unitholders': [
            {
                'id: 1,
                'first_name': 'myfirstname',
                'last_name': 'mylastname',
                'unitholder_type': 'renter'
            }
        ]
    }
]

我很确定我的问题出在我的 UnitSerializer 中,但我是 DRF 的新手,并且通读了文档,但似乎仍然无法弄清楚。

【问题讨论】:

    标签: python json django django-rest-framework


    【解决方案1】:

    一个简单的解决方案是使用depth 选项:

    class UnitSerializer(serializers.ModelSerializer):
        unit_type = serializers.SlugRelatedField(
            queryset=UnitType.objects.all(), slug_field='description'
        )
    
        class Meta:
            model = Unit
            fields = ('unit_number', 'unit_type', 'unitholders')
            depth = 1
    

    这将序列化所有嵌套关系 1 级深度。如果您想更好地控制每个嵌套字段的序列化方式,您可以显式列出它们的序列化器:

    class UnitSerializer(serializers.ModelSerializer):
        unit_type = serializers.SlugRelatedField(
            queryset=UnitType.objects.all(), slug_field='description'
        )
        unitholders = UnitHolderSerializer(many=True)
    
        class Meta:
            model = Unit
            fields = ('unit_number', 'unit_type', 'unitholders')
    

    另外作为附注,您需要考虑将视图中的查询集修改为prefetch related objects,否则您将很快破坏应用程序的性能(使用django-debug-toolbar 之类的东西来监控生成的查询非常方便):

    class UnitViewSet(viewsets.ModelViewSet):
        queryset = Unit.objects.all().select_related('unit_type').prefetch_related('unitholders')
        serializer_class = UnitSerializer
    

    【讨论】:

    • 谢谢!这一切都非常有帮助。 depth = 1 对我有用,但通过错误明确列出了序列化程序。我会尝试自己解决这些问题:)
    • 我刚刚意识到 "'unitholder_type': 'renter'" 没有被退回。 unitholder 类型被保存在关联“Unit”和“Person”的连接表中。我不仅想返回与此人关联的单位,还想返回联接本身中保存的关联类型。
    【解决方案2】:

    也许你必须这样做:

    class UnitHolderViewSet(viewsets.ModelViewSet):
        queryset = UnitHolder.objects.all()
        unitholders = UnitHolderSerializer(read_only=True, many=True)
    

    Django rest framework serializing many to many field

    【讨论】:

    • 嗯。谢谢。我只是将其添加到我的视图中,但没有任何效果。查询该端点仍然返回:[{'unit_type': 'Home', 'unit_number': 614, 'unitholders': [1]}]
    猜你喜欢
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2021-09-18
    相关资源
    最近更新 更多