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

如何在Django REST Framework中序列化嵌套泛型关系返回关联字段

Django REST Framework 泛型外键关联字段序列化实现方案

实现思路

使用DRF内置的SerializerMethodField自定义返回字段,遍历Person实例关联的Mapping对象,校验泛型外键的关联类型后提取对应的Company.name和Profile.rank,拼装为要求的字典列表格式返回。你现有的查询集已经做了关联预加载,不会新增额外的数据库查询。

前置代码修正

先修复你示例代码中的语法错误,避免运行时报错:

  • Person模型的ptype字段在序列化器中误写为type,需同步修改
  • Company模型定义漏写右括号、字段类名大小写错误,修正为class Company(models.Model):与name = models.CharField()
  • Profile模型的外键拼写错误,修正为company = models.ForeignKey("Company")
  • PersonSerializer类定义漏写冒号,修正为class PersonSerializer(serializers.ModelSerializer):

序列化器实现代码

from rest_framework import serializers
# 确保导入你的模型类
from .models import Person, Profile

class PersonSerializer(serializers.ModelSerializer):
    # 新增自定义返回字段
    company_rank_info = serializers.SerializerMethodField()

    class Meta:
        model = Person
        fields = (
            'id',
            'first_name',
            'last_name',
            'ptype',
            'company_rank_info'
        )
    
    def get_company_rank_info(self, obj):
        result_list = []
        # 若1个Person对应多个Mapping,将下方改为 for mapping in obj.mapping.all() 遍历即可
        mapping_obj = obj.mapping
        # 校验泛型外键关联对象类型为Profile,避免其他类型关联导致报错
        if hasattr(mapping_obj, 'mapped_profile_object') and isinstance(mapping_obj.mapped_profile_object, Profile):
            company_name = mapping_obj.company.name
            profile_rank = mapping_obj.mapped_profile_object.rank
            result_list.append({company_name: profile_rank})
        return result_list

可选适配调整

如果你的业务逻辑是1个Person对应多个Mapping关联,只需做两处调整:

  1. 将Person模型中到Mapping的外键改为反向关联,或者修改为ManyToManyField
  2. 将上面方法中的单行取值改为遍历obj.mapping.all(),依次拼装字典即可

内容的提问来源于stack exchange,提问作者Sencer H.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 23:21:01