如何在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
相关产品推荐
相关产品推荐

