我有一个api,它通过带有额外订单字段的manytomany模型检索与项目相关的所有项目。我现在正在尝试使用订单值序列化项目。
一种解决方案是序列化直通模型,但结果如下:
{
"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')
有什么想法吗?
答案 0 :(得分:4)
如果您有直通模型,那么您应该对其进行序列化并使用source
额外参数来“展平”表示。
例如,对于name
,它将是
name = serializers.CharField(source='item.name')
您可能必须编写序列化程序创建/更新方法,以使其适用于可写。
答案 1 :(得分:0)
如果由于某些原因不希望像@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]获取预取值的第一个对象