Django DRF序列化器如何根据外键关联方向动态返回不同字段
解决方案
你可以通过DRF序列化器动态裁剪字段的能力实现需求,无需创建多套序列化器,也不需要调整模型结构。
方案1:传参控制排除字段(推荐,耦合低、复用性强)
先重写ActorRoleSerializer的初始化方法,支持传入要排除的字段列表:
class ActorRoleSerializer(serializers.ModelSerializer): film = serializers.CharField(source='film.title') actor = serializers.CharField(source='person.name') class Meta: model = ActorRole fields = ['actor', 'role', 'film'] def __init__(self, *args, **kwargs): exclude_fields = kwargs.pop('exclude_fields', None) super().__init__(*args, **kwargs) # 初始化时移除不需要的字段 if exclude_fields: for field in exclude_fields: self.fields.pop(field, None)
然后在嵌套序列化时传入对应要排除的字段即可:
class FilmSerializer(serializers.ModelSerializer): # 查询电影时排除film字段,只保留actor和role cast = ActorRoleSerializer(many=True, read_only=True, exclude_fields=['film']) class Meta: model = Film fields = ['id', 'title', 'cast'] class PersonSerializer(serializers.ModelSerializer): # 查询演员时排除actor字段,只保留film和role filmCredits = ActorRoleSerializer(many=True, read_only=True, exclude_fields=['actor']) class Meta: model = Person fields = ['id', 'name', 'filmCredits']
方案2:自动识别父序列化器(无额外传参,更省心)
如果不想在嵌套时传参数,也可以在ActorRoleSerializer的初始化方法中自动判断父序列化器类型,自动裁剪字段:
class ActorRoleSerializer(serializers.ModelSerializer): film = serializers.CharField(source='film.title') actor = serializers.CharField(source='person.name') class Meta: model = ActorRole fields = ['actor', 'role', 'film'] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) parent = self.parent if not parent: return # 根据父序列化器类型自动移除冗余字段 if isinstance(parent, FilmSerializer): self.fields.pop('film', None) elif isinstance(parent, PersonSerializer): self.fields.pop('actor', None)
这种方案不需要修改原有嵌套序列化的代码,适合只有这两种关联场景的需求。
两种方案都能完全匹配你需要的返回格式,没有冗余字段。
内容的提问来源于stack exchange,提问作者sstoxen
相关产品推荐
相关产品推荐

