You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tortoise ORM无blank=False配置,如何禁止存储空字符串

问题根因

Tortoise ORM 中字段的null=False配置仅限制字段不能存储None值,空字符串''属于合法的字符串类型值,默认不会被拦截。这和Django中null控制数据库层面非空、blank控制业务层面不允许空值的分工逻辑不同,Tortoise本身没有内置blank校验参数,需要自行补充校验逻辑。

解决方案

建议同时在Pydantic序列化层和ORM层配置校验,前者拦截接口层的非法输入,后者作为兜底避免绕过接口直接操作ORM时写入脏数据。

1. ORM模型层面加校验

Tortoise 支持重写模型的clean()方法自定义校验规则,调用create()、save()方法时会自动触发该校验:

from tortoise.exceptions import ValidationError
from tortoise.models import Model
from tortoise import fields

class User(Model):
    id = fields.IntField(pk=True)
    email = fields.CharField(100, unique=True, index=True)
    password = fields.CharField(128)
    name = fields.CharField(50)
    surname = fields.CharField(50)

    def clean(self):
        # 校验指定字符串字段不可为空或纯空白
        str_fields = ["email", "password", "name", "surname"]
        for field_name in str_fields:
            value = getattr(self, field_name)
            if isinstance(value, str) and value.strip() == "":
                raise ValidationError(f"{field_name} 字段不能是空字符串或纯空白字符")

如果多个模型都需要类似校验,可以把clean()逻辑封装到自定义BaseModel基类中,所有业务模型继承该基类即可。

2. Pydantic Schema层面加校验

在序列化层直接加字段约束,提前拦截非法参数,这里以Pydantic v2为例:

from pydantic import BaseModel, Field, field_validator

class UserCreateSchema(BaseModel):
    email: str = Field(min_length=1, max_length=100)
    password: str = Field(min_length=1, max_length=128)
    name: str = Field(min_length=1, max_length=50)
    surname: str = Field(min_length=1, max_length=50)

    # 额外校验不能是纯空白字符
    @field_validator("email", "name", "surname", "password")
    @classmethod
    def check_not_blank(cls, value: str) -> str:
        if value.strip() == "":
            raise ValueError("字段不能为空白字符串")
        return value

3. 自定义全局字段类型(可选)

如果项目大量场景需要禁止空字符串的CharField,可以自定义字段类型实现一劳永逸:

from tortoise import fields
from tortoise.exceptions import ValidationError

class NonBlankCharField(fields.CharField):
    def validate(self, value, model_instance):
        super().validate(value, model_instance)
        if isinstance(value, str) and value.strip() == "":
            raise ValidationError(f"{self.model_field_name} 字段不能是空字符串")

业务模型直接替换原生CharField即可:

class User(Model):
    id = fields.IntField(pk=True)
    email = NonBlankCharField(100, unique=True, index=True)
    password = NonBlankCharField(128)
    name = NonBlankCharField(50)
    surname = NonBlankCharField(50)

内容的提问来源于stack exchange,提问作者Hahan't

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 18:09:03