如何使用反向相关模型中的字段进行序列化 - Django rest framework

How to Serialize with field from reverse related model - Django rest framework

我有一个 api,它通过带有额外订单字段的多对多模型检索与项目相关的所有项目。我现在正在尝试序列化带有订单值的项目。

一种解决方案是序列化 through 模型,但这会产生如下结果:

{
    "order": 1,
    "item": {
        "id": 3031,
        "name": "Miami"
    }
},

我想改为序列化该项目并获得如下输出:

{
    "order": 1,
    "id": 3031,
    "name": "Miami"
}

我无法将订单作为属性添加到项目模型,因为它是一个多对多字段。或者我想我可以但必须采用列表的第一个对象,这不是我认为非常干净的解决方案,可能会添加一个单独的数据库调用。

所有项目都是这样获取的:

ProjectItem.objects.filter(project_id=self.kwargs['project_pk']).select_related('item')

有什么想法吗?

如果您有直通模型,则应将其序列化并使用 source 额外参数 "flatten" 表示。

例如,对于 name,它将是

name = serializers.CharField(source='item.name')

您可能必须编写序列化程序创建/更新方法才能使其可写。

如果您出于某种原因不想像@Linovia 建议的那样通过直通模型,那么您可以预取直通模型并使用具有覆盖 to_representation.

的 RelatedField

这是我所做的:

from django.db.models import Prefetch

Item.objects.filter(projectitem_set__project_id=self.kwargs['project_pk'])
    .prefetch_related(
        Prefetch('projectitem_set', queryset=ProjectItem.objects.filter(project_id=self.kwargs['project_pk']), to_attr='order'))

然后将其添加到 ItemSerializer(不要添加 many=True):

order = ProjectItemSerializer(read_only=True)

并覆盖 ProjectItemSerializer 中的 to_representation:

class ProjectItemSerializer(serializers.RelatedField):
    def to_representation(self, value):
        return value[0].order

value[0] 获取预取值的第一个对象