Django嵌套序列化器POST请求报错:tags.videoId不可为null
解决Django嵌套POST请求创建关联标签的400错误
问题核心
你遇到的400错误是因为序列化器验证在create方法执行前就失败了:VideoVideoTagSerializer会默认验证videoId字段不为空(模型中该外键未设置null=True),但你提交的tags数据里videoId是null,直接触发验证错误,导致重写的create方法根本没机会执行。
解决方案
1. 修改VideoVideoTagSerializer,标记videoId为只读字段
videoId是关联视频的外键,创建视频后后端会自动赋值,不需要前端传入。修改序列化器:
class VideoVideoTagSerializer(serializers.ModelSerializer): class Meta: model = VideoVideoTag fields = ('id', 'videoTagId') # 或者通过read_only_fields明确标记,保留所有字段但忽略videoId的验证: # read_only_fields = ('videoId',)
这样序列化器就不会要求前端传入videoId,也不会验证该字段的非空性。
2. 修正VideoManageSerializer的create方法
注意模型VideoVideoTag的外键字段名是videoId,创建关联时要对应这个字段名,而不是默认的video:
class VideoManageSerializer(serializers.ModelSerializer): tags = VideoVideoTagSerializer(many=True) class Meta: model = Video fields = '__all__' def create(self, validated_data): tags_data = validated_data.pop('tags') # 创建视频实例 video_instance = Video.objects.create(**validated_data) # 批量创建关联标签 for tag_data in tags_data: VideoVideoTag.objects.create( videoId=video_instance, **tag_data ) return video_instance
3. 调整前端提交的数据
移除tags里的videoId字段,提交的JSON可以改为:
{ "id":null, "deleted":false, "publishedOn":"2022-11-28", "decoratedThumbnail":"https://t3.ftcdn.net/jpg/02/48/42/64/360_F_248426448_NVKLywWqArG2ADUxDq6QprtIzsF82dMF.jpg", "rawThumbnail":"https://t3.ftcdn.net/jpg/02/48/42/64/360_F_248426448_NVKLywWqArG2ADUxDq6QprtIzsF82dMF.jpg", "videoUrl":"https://www.youtube.com/watch?v=jNQXAC9IVRw", "title":"Video with tags", "duration":120, "visibility":1, "tags":[ { "id":null, "videoTagId":42 } ] }
额外注意事项
- 确保
VisibilityType模型中存在id=1的记录,否则创建视频时会因外键不存在报错。 - 模型
VideoVideoTag的外键字段名videoId不符合Django命名规范(通常用video_id),后续维护建议修改字段名并调整db_column,避免混淆。
内容的提问来源于stack exchange,提问作者Marco Fregoso
相关产品推荐
相关产品推荐

