为何Django Rest Framework会忽略模型字段默认值?
为什么会出现这些行为?
第一个场景(无blank、null)
你的模型字段some_field = models.CharField(default='Yes')默认不允许存储NULL值(null=False是CharField的默认设置),同时Django Rest Framework的ModelSerializer会自动根据模型字段的约束生成验证规则。当你POST请求中显式传递{'some_field': None}时,序列化器会验证这个值不符合字段的非空要求,因此返回400错误,这是预期行为。
第二个场景(添加blank=True、null=True)
当你给模型字段加上blank=True, null=True后,字段允许存储NULL值,序列化器的验证会通过。但此时你显式传递了None,Django会将这个值直接写入数据库,而不会使用字段的默认值——因为默认值仅在字段未被赋值时才会生效,显式传递None属于主动赋值操作,所以最终字段值会被设为NULL,这同样是预期行为。
如何实现「用户传递null时使用默认值」?
如果希望用户传递None或null时,依然使用模型的默认值,可以通过以下几种方式修改序列化器:
1. 在序列化器字段上设置默认值
直接在序列化器中定义字段并指定default,覆盖或对齐模型的默认值逻辑:
class MyClassSerializer(serializers.ModelSerializer): some_field = serializers.CharField(default='Yes') class Meta: model = MyClass fields = ['some_field']
这样无论用户传递None还是不传递该字段,都会使用'Yes'作为值。
2. 自定义字段验证方法
通过validate_some_field方法将None替换为默认值:
class MyClassSerializer(serializers.ModelSerializer): class Meta: model = MyClass fields = ['some_field'] def validate_some_field(self, value): # 若值为None,返回默认值,否则返回原value return value if value is not None else 'Yes'
3. 重写序列化器的create方法
在创建实例前,检查validated_data中的字段值,若为None则替换为默认值:
class MyClassSerializer(serializers.ModelSerializer): class Meta: model = MyClass fields = ['some_field'] def create(self, validated_data): # 处理显式传递None的情况 if validated_data.get('some_field') is None: validated_data['some_field'] = 'Yes' # 同时处理未传递字段的场景 validated_data.setdefault('some_field', 'Yes') return super().create(validated_data)
补充说明
如果用户的POST请求不包含some_field字段,无论模型是否设置blank和null,DRF都会自动使用模型字段的默认值——因为此时validated_data中没有该字段,Django会在创建模型实例时应用默认值。只有当用户**显式传递None**时,才需要额外处理。
内容的提问来源于stack exchange,提问作者Jorhanc

