如何使用反向相关模型中的字段进行序列化 - 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] 获取预取值的第一个对象
我有一个 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] 获取预取值的第一个对象