Nav*_*een 4 python sqlalchemy pydantic
用户的 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)
Run Code Online (Sandbox Code Playgroud)
我的 pydantic 模型是
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]
Run Code Online (Sandbox Code Playgroud)
我想为电话号码创建一个自定义数据类型...这样我可以在多个地方使用它...我正在尝试如下
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
Run Code Online (Sandbox Code Playgroud)
通过邮递员,我正在发送
{
"phone": "+917777777777"
}
Run Code Online (Sandbox Code Playgroud)
我在邮递员中看到 400 错误
[
{
"loc": [
"phone",
"phone"
],
"msg": "field required",
"type": "value_error.missing"
}
]
Run Code Online (Sandbox Code Playgroud)
关于我上面做错了什么的任何输入
这不起作用,因为您正在传递:
{
"phone": "+917777777777"
}
Run Code Online (Sandbox Code Playgroud)
而模型具有结构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
Run Code Online (Sandbox Code Playgroud)
改为发送此内容:
{
"phone": {
"phone": "+917777777777"
}
}
Run Code Online (Sandbox Code Playgroud)
现在应该可以了。
validator到父模型我认为以下内容更符合您的要求:
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
Run Code Online (Sandbox Code Playgroud)
这样你就可以phone按照你所期望的那样传入正文:
{
"phone": "+917777777777"
}
Run Code Online (Sandbox Code Playgroud)
假设您使用 FastAPI,在这两种情况下,如果电话号码太短、太长或包含无效字符,您会收到以下错误:
{
"detail": [
{
"loc": [
"body",
"phone"
],
"msg": "Phone Number Invalid.",
"type": "value_error"
}
]
}
Run Code Online (Sandbox Code Playgroud)
Pydantic 有一个constr(约束字符串)类型,它允许您定义最小和最大长度以及其他一些东西。您可以使用以下内容代替str该phone字段,例如:
class UserPatchEntity(BaseModel):
...
phone: Optional[
constr(
strip_whitespace=True,
min_length=9,
max_length=15,
)
]
Run Code Online (Sandbox Code Playgroud)
它还允许您直接指定一个regex字符串,例如:
class UserPatchEntity(BaseModel):
...
phone: Optional[
constr(
strip_whitespace=True,
regex=r"^(\+)[1-9][0-9\-\(\)\.]{9,15}$",
)
]
Run Code Online (Sandbox Code Playgroud)
这将节省您编写显式的validator.
如果您继续“直接”使用正则表达式,我建议compile()他们让它们更快一点。
http://localhost:8000/docs假设您使用的是 FastAPI,当应用程序运行时,您可以导航到,您将在其中找到完整的 OpenAPI 界面。您可以直接从那里发送有效负载,它还会显示每个端点的签名。在第一种情况下,如果您定义了这样的端点:
@router.post("/user/")
async def post_user(user_patch_entity: UserPatchEntity):
return user_patch_entity.phone
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7091 次 |
| 最近记录: |