Django REST重写create方法时提取POST请求documentId参数问题
问题原因
你在validated_data中始终拿不到documentId,核心原因和取值方法无关:
- 你的序列化器
Meta.fields列表里没有声明documentId字段,也没有在序列化器类中显式定义该字段 - DRF默认会在数据校验阶段直接过滤掉所有未声明的入参字段,这类字段根本不会进入
validated_data,所以不管用.get()还是下标取值都会报错。 - 你之前考虑的修改
DocumentListingField的read_only属性的方案会触发HashField序列化兼容问题,完全没必要走,有更轻量的无侵入方案。
实现方案
不需要改动现有Document字段的任何配置,只需要额外新增一个仅用于接收入参的只写字段即可,完全不会影响原有序列化输出逻辑,也不会触发Document模型的HashField序列化问题。
修改后的完整序列化器代码:
from django.forms.models import model_to_dict from rest_framework import serializers from .models import MySource, Document class DocumentListingField(serializers.RelatedField): def to_representation(self, instance): return model_to_dict(instance.document) class MySourceSerializer(serializers.ModelSerializer): Document = DocumentListingField(many=False, read_only=True) # 新增只写字段,仅接收写入的documentId参数,不会参与接口返回的序列化 documentId = serializers.CharField(write_only=True, required=True) class Meta: model = MySource fields = ( "id", "url", "title", "publisher", "desc", "summary", "Document", "documentId", # 必须将字段加入fields列表,否则入参会被默认过滤 ) def create(self, validated_data): # pop取出参数,避免后续create时传入未知字段报错 document_id = validated_data.pop("documentId") source = MySource.objects.create( document=Document.objects.get(id=document_id), **validated_data ) return source
方案注意点
- 新增的
documentId字段配置write_only=True后,只会在入参校验阶段生效,接口返回响应时不会输出该字段,完全不破坏原有返回结构 - 该字段是独立的字符串类型字段,和原有
DocumentListingField完全解耦,不会触发Document模型的HashField序列化逻辑,不会出现兼容性问题 - 原代码中
validated_data.get("documentId").末尾多余的点是语法错误,已经修正;objects.create方法会直接完成数据入库,不需要额外调用source.save()。
内容的提问来源于stack exchange,提问作者Tyler Kim
相关产品推荐
相关产品推荐

