为什么Django序列化器中显式指定read_only的字段仍可写入?
Django序列化器只读字段不生效问题解决方案
问题复现
你配置的category_info字段显式声明了read_only=True,但实际请求携带该字段时仍然会被序列化器处理,没有被忽略。
排查与解决步骤
- 第一步:先确认字段配置是否被其他逻辑覆盖
执行以下代码确认字段的实际属性:
如果输出为ser = ProductSerializer(data={}) print(ser.fields['category_info'].read_only)False,说明你的配置被覆盖,重点排查两处:- 序列化器
__init__方法中是否有动态修改fields属性的逻辑,修改了category_info的read_only参数 - 继承的父类序列化器中是否声明了同名
category_info字段,父类配置优先级低于子类显式声明,若存在父类配置可在子类重新声明覆盖
- 序列化器
- 第二步:升级DRF版本
DRF 3.10之前的旧版本存在嵌套序列化器显式配置read_only不生效的已知bug,升级到最新稳定版即可解决:pip install --upgrade djangorestframework - 第三步:检查自定义校验逻辑
若你编写了def validate_category_info的字段级校验方法,即使字段设为只读,DRF仍会将请求中的category_info参数传入该方法,看起来像是字段可写入,直接删除对应字段的自定义校验逻辑即可。 - 第四步:兜底强制过滤字段
上述方案都不生效时,重写to_internal_value方法强制移除传入的category_info参数:class ProductSerializer(serializers.ModelSerializer): category_info = CategorySerializer(source="category", read_only=True) class Meta: model = Card fields = ('id','title','description','category',) + ('category_info',) extra_kwargs = {'category': {'write_only': True},} def to_internal_value(self, data): data.pop('category_info', None) return super().to_internal_value(data)
内容的提问来源于stack exchange,提问作者Jasmeet Pabla
相关产品推荐
相关产品推荐

