简体   繁体   English

电话号码的 pydantic 自定义数据类型:value_error.missing

[英]pydantic custom data type for phone number : value_error.missing

mysql schema for user用户的 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)

my pydantic model is我的 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]

i want to create a custom datatype for phone number...so i can use it at multiple places....i am trying like below我想为电话号码创建一个自定义数据类型......所以我可以在多个地方使用它......我正在尝试如下

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

via postman, i am sending通过 postman,我正在发送

{
    "phone": "+917777777777"
}

i see 400 error in postman我在 postman 中看到 400 错误

[
    {
        "loc": [
            "phone",
            "phone"
        ],
        "msg": "field required",
        "type": "value_error.missing"
    }
]

Any inputs on what i am doing wrong above关于我在上面做错的任何输入

This doesn't work because you are passing in:这不起作用,因为您正在传递:

{
    "phone": "+917777777777"
}

while the model has the structure UserPatchEntity.Phone.phone .而 model 具有结构UserPatchEntity.Phone.phone

In order to make this work, I see two options:为了完成这项工作,我看到了两个选项:

1. Adapt the JSON Body (and fix the validator ) 1.适配JSON Body(并修复validator

Fixing the 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

Send this instead:改为发送:

{
  "phone": {
    "phone": "+917777777777"
  }
}

It should work now.它现在应该可以工作了。

2. Move the validator to the Parent Model 2. 将validator移至父 Model

I would assume that the following is more in line what you want:我会假设以下内容更符合您的要求:

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

With that you can pass in phone in the body as you would expect:有了它,您可以按预期将phone传递到体内:

{
    "phone": "+917777777777"
}

Assuming you're using FastAPI, in both cases, you'd get the following error if the phone number is too short, too long, or contains invalid characters:假设您使用的是 FastAPI,在这两种情况下,如果电话号码太短、太长或包含无效字符,您都会收到以下错误:

{
  "detail": [
    {
      "loc": [
        "body",
        "phone"
      ],
      "msg": "Phone Number Invalid.",
      "type": "value_error"
    }
  ]
}

NOTES/HINTS:注释/提示:

  • Pydantic has a constr (Constrained String) type, which allows you to define the minimum and maximum length, and a few other things. constr有一个 constr(约束字符串)类型,它允许您定义最小和最大长度,以及其他一些东西。 You could use the following instead of str for the phone field, eg:您可以将以下内容代替str用于phone字段,例如:

     class UserPatchEntity(BaseModel): ... phone: Optional[ constr( strip_whitespace=True, min_length=9, max_length=15, ) ]

    It also allows you to directly specify a regex string, eg:它还允许您直接指定regex字符串,例如:

     class UserPatchEntity(BaseModel): ... phone: Optional[ constr( strip_whitespace=True, regex=r"^(\+)[1-9][0-9\-\(\)\.]{9,15}$", ) ]

    Which would save you writing the explicit validator .这样可以节省您编写显式validator的时间。

  • If you continue using regular expressions "directly", I would suggest to compile() them to make them a bit faster.如果您继续“直接”使用正则表达式,我建议您compile()它们以使它们更快一点。

  • Assuming you are using FastAPI, you can navigate to http://localhost:8000/docs , when the app is running, where you'll find a full OpenAPI interface.假设您使用的是 FastAPI,您可以在应用程序运行时导航到http://localhost:8000/docs ,您将在其中找到完整的 OpenAPI 接口。 You can send payloads directly from there and it also shows you the signature for each endpoint.您可以直接从那里发送有效负载,它还会向您显示每个端点的签名。 In the first case, if you defined an endpoint like this:在第一种情况下,如果您定义了这样的端点:

     @router.post("/user/") async def post_user(user_patch_entity: UserPatchEntity): return user_patch_entity.phone

    it would show the documentation like that:它会显示这样的文档: 在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 嵌套 Pydantic Model 使用 FastAPI 返回错误:需要字段(type=value_error.missing) - Nested Pydantic Model return error with FastAPI : field required (type=value_error.missing) pydantic.error_wrappers.ValidationError:For Trip type=value_error.missing 的 11 个验证错误 - pydantic.error_wrappers.ValidationError: 11 validation errors for For Trip type=value_error.missing Pydantic 嵌套 model 字段抛出 value_error.missing - Pydantic nested model field throws value_error.missing postman api 说“422 无法处理的实体” - value_error.missing - postman api says "422 unprocessable entity" - value_error.missing 如果我进行查询,为什么会得到 {"detail":[{"loc":["path","id"],"msg":"field required","type":"value_error.missing"}]}与参数? - Why am I getting {"detail":[{"loc":["path","id"],"msg":"field required","type":"value_error.missing"}]} if I made query with params? 在后端使用快速 api 和 mongo; 为获取请求获取“value_error.missing” - Using fast api and mongo in backend; getting “value_error.missing” for get request pydantic.error_wrappers.ValidationError:值不是有效列表(type=type_error.list) - pydantic.error_wrappers.ValidationError : value is not a valid list (type=type_error.list) Pydantic:检测字段值是否缺失或作为 null - Pydantic: Detect if a field value is missing or given as null Python pydantic model 传递 None 作为 int 值不是有效的 integer (type=type_error.integer) - Python pydantic model passing None as int value is not a valid integer (type=type_error.integer) Pydantic json 值在自定义枚举上为空 - Pydantic json value is empty on Custom Enum
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM