![](/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.