You need to enable JavaScript to run this app. 为什么Django序列化器中显式指定read_only的字段仍可写入?
优惠活动
大模型
产品
解决方案
定价
更多

为什么Django序列化器中显式指定read_only的字段仍可写入?

Django序列化器只读字段不生效问题解决方案

问题复现

你配置的category_info字段显式声明了read_only=True,但实际请求携带该字段时仍然会被序列化器处理,没有被忽略。

排查与解决步骤

  • 第一步:先确认字段配置是否被其他逻辑覆盖
    执行以下代码确认字段的实际属性:
    ser = ProductSerializer(data={})
    print(ser.fields['category_info'].read_only)
    
    如果输出为False,说明你的配置被覆盖,重点排查两处:
    1. 序列化器__init__方法中是否有动态修改fields属性的逻辑,修改了category_info的read_only参数
    2. 继承的父类序列化器中是否声明了同名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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.09 22:45:03