如何在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关联,只需做两处调整:
- 将Person模型中到Mapping的外键改为反向关联,或者修改为
ManyToManyField - 将上面方法中的单行取值改为遍历
obj.mapping.all(),依次拼装字典即可
内容的提问来源于stack exchange,提问作者Sencer H.
相关产品推荐
相关产品推荐

