You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django REST Framework中合并两个反向外键为单个JSON字段

解决方案

你可以通过DRF的SerializerMethodField自定义字段,合并两个反向关联的子对象ID,生成单独的children字段,完全在序列化器层面实现需求,无需修改模型。

修改后的序列化器代码

from rest_framework.serializers import ModelSerializer, SerializerMethodField
from .models import Person

class FamilySerializer(ModelSerializer):
    children = SerializerMethodField()

    def get_children(self, obj):
        # 收集当前对象作为母亲的孩子ID
        mother_children = [child.id for child in obj.children_as_mother.all()]
        # 收集当前对象作为父亲的孩子ID
        father_children = [child.id for child in obj.children_as_father.all()]
        # 合并列表并去重(防止同一孩子同时关联两个身份),再排序保证结果一致性
        combined_children = list(set(mother_children + father_children))
        combined_children.sort()
        return combined_children

    class Meta:
        model = Person
        fields = [
            "pk",
            "first_name",
            "last_name",
            "mother",
            "father",
            "children",
        ]

优化视图查询性能

为了避免序列化时出现N+1数据库查询问题,在视图集中给查询集添加预取关联:

from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet
from .models import Person
from .serializers import FamilySerializer

class FamilyViewSet(ModelViewSet):
    """
    API endpoint with family data
    """
    queryset = Person.objects.all().prefetch_related('children_as_mother', 'children_as_father')
    serializer_class = FamilySerializer
    permission_classes = [IsAuthenticated]

效果说明

修改后,API响应会生成你期望的JSON结构:每个Person对象都包含一个children字段,里面是该对象所有子女的ID集合,替换了原来的children_as_mother和children_as_father两个字段。

内容的提问来源于stack exchange,提问作者ap0

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 08:16:00