Django Rest Framework 能否仅用单序列化器实现GET返回外键全对象、POST仅收外键ID
实现方案
完全可以实现需求,且不需要新增额外序列化器类,仅需调整现有代码即可。
首先需要修正现有代码的配置错误:
SongSerializer的Meta类中model字段误写为Singer,需改为绑定Song模型,否则序列化器逻辑完全错误。
修改后的完整代码
# SingerSerializer 无需做任何修改 class SingerSerializer(serializers.ModelSerializer): class Meta: model = Singer fields = '__all__' class SongSerializer(serializers.ModelSerializer): class Meta: # 修正原有错误配置 model = Song fields = '__all__' def to_representation(self, instance): # 调用父类获取默认序列化结果,此时singer字段默认输出外键ID base_rep = super().to_representation(instance) # 将singer字段替换为完整嵌套对象 base_rep['singer'] = SingerSerializer(instance.singer).data return base_rep
实现逻辑说明
- 移除手动声明的
singer = SingerSerializer()后,ModelSerializer 会自动为singer外键生成PrimaryKeyRelatedField:- 处理POST/PATCH请求时,该字段原生就支持仅传入外键ID,自动校验ID对应的歌手是否存在,校验通过后自动绑定到歌曲实例,完全匹配你期望的请求载荷格式。
- 处理GET请求时,默认输出singer的ID。
- 重写
to_representation方法,在默认输出的基础上,把singer字段的值从ID替换为用现有SingerSerializer序列化的完整对象,即可实现GET响应返回嵌套歌手结构的需求。
效果验证
GET 请求响应结构
{ "id": 1, "title": "foo la la", "singer": { "id": 1, "name": "foo" } }
PATCH/POST 请求载荷示例
{ "title": "foo la la", "singer": 1 }
内容的提问来源于stack exchange,提问作者Judy T Raj
相关产品推荐
相关产品推荐

