![](/img/trans.png)
[英]Nested Pydantic Model return error with FastAPI : field required (type=value_error.missing)
[英]pydantic custom data type for phone number : value_error.missing
用户的 mysql 架构
user_id binary(16)
first_name varchar(32)
last_name varchar(32)
email varchar(255)
phone varchar(32)
role enum('member','admin','operator')
created_on datetime
updated_on datetime
id varchar(32)
我的 pydantic model 是
class UserPatchEntity(BaseModel):
user_id: Optional[UUID]
first_name: Optional[str] = Field(min_length=1, max_length=32)
last_name: Optional[str] = Field(min_length=1, max_length=32)
email: Optional[EmailStr]
phone: Optional[Phone]---------------> HERE
role: Optional[RoleType]
我想为电话号码创建一个自定义数据类型......所以我可以在多个地方使用它......我正在尝试如下
class Phone(BaseModel):
phone: str
@validator('phone')
def phone_validation(cls, v):
phone = v.phone.get("phone")
logger.debug(f"phone in 2 validator:{v}")
regex = r"^(\+)[1-9][0-9\-\(\)\.]{9,15}$"
if v and not re.search(regex, v, re.I):
raise ValueError("Phone Number Invalid.")
return v
class Config:
orm_mode = True
use_enum_values = True
通过 postman,我正在发送
{
"phone": "+917777777777"
}
我在 postman 中看到 400 错误
[
{
"loc": [
"phone",
"phone"
],
"msg": "field required",
"type": "value_error.missing"
}
]
关于我在上面做错的任何输入
这不起作用,因为您正在传递:
{
"phone": "+917777777777"
}
而 model 具有结构UserPatchEntity.Phone.phone
。
为了完成这项工作,我看到了两个选项:
validator
) 修复validator
:
class Phone(BaseModel):
phone: str
@validator("phone")
def phone_validation(cls, v):
# phone = v.phone.get("phone") # <-- This line needs to be removed.
logger.debug(f"phone in 2 validator:{v}")
regex = r"^(\+)[1-9][0-9\-\(\)\.]{9,15}$"
if v and not re.search(regex, v, re.I):
raise ValueError("Phone Number Invalid.")
return v
class Config:
orm_mode = True
use_enum_values = True
改为发送:
{
"phone": {
"phone": "+917777777777"
}
}
它现在应该可以工作了。
validator
移至父 Model我会假设以下内容更符合您的要求:
class UserPatchEntity(BaseModel):
user_id: Optional[UUID]
first_name: Optional[str] = Field(min_length=1, max_length=32)
last_name: Optional[str] = Field(min_length=1, max_length=32)
email: Optional[EmailStr]
phone: Optional[str] # <-- This is a str now, everything else stays the same
role: Optional[RoleType]
@validator("phone")
def phone_validation(cls, v):
logger.debug(f"phone in 2 validator:{v}")
regex = r"^(\+)[1-9][0-9\-\(\)\.]{9,15}$"
if v and not re.search(regex, v, re.I):
raise ValueError("Phone Number Invalid.")
return v
class Config:
orm_mode = True
use_enum_values = True
有了它,您可以按预期将phone
传递到体内:
{
"phone": "+917777777777"
}
假设您使用的是 FastAPI,在这两种情况下,如果电话号码太短、太长或包含无效字符,您都会收到以下错误:
{
"detail": [
{
"loc": [
"body",
"phone"
],
"msg": "Phone Number Invalid.",
"type": "value_error"
}
]
}
constr
有一个 constr(约束字符串)类型,它允许您定义最小和最大长度,以及其他一些东西。 您可以将以下内容代替str
用于phone
字段,例如:
class UserPatchEntity(BaseModel): ... phone: Optional[ constr( strip_whitespace=True, min_length=9, max_length=15, ) ]
它还允许您直接指定regex
字符串,例如:
class UserPatchEntity(BaseModel): ... phone: Optional[ constr( strip_whitespace=True, regex=r"^(\+)[1-9][0-9\-\(\)\.]{9,15}$", ) ]
这样可以节省您编写显式validator
的时间。
如果您继续“直接”使用正则表达式,我建议您compile()
它们以使它们更快一点。
假设您使用的是 FastAPI,您可以在应用程序运行时导航到http://localhost:8000/docs
,您将在其中找到完整的 OpenAPI 接口。 您可以直接从那里发送有效负载,它还会向您显示每个端点的签名。 在第一种情况下,如果您定义了这样的端点:
@router.post("/user/") async def post_user(user_patch_entity: UserPatchEntity): return user_patch_entity.phone
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.