我想知道:
from pydantic import BaseModel, Field
class Person(BaseModel):
name: str = Field(..., min_length=1)
和:
from pydantic import BaseModel, constr
class Person(BaseModel):
name: constr(min_length=1)
两者似乎都执行相同的验证(甚至在
name
为空字符串时引发完全相同的异常信息)。这只是代码风格的问题吗?其中之一优于另一个吗?
另外,如果我想包含非空字符串列表作为属性,您认为以下哪种方式更好?:
from typing import List
from pydantic import BaseModel, constr
class Person(BaseModel):
languages: List[constr(min_length=1)]
或者:
from typing import List
from pydantic import BaseModel, Field
class Person(BaseModel):
languages: List[str]
@validator('languages', each_item=True)
def check_nonempty_strings(cls, v):
if not v:
raise ValueError('Empty string is not a valid language.')
return v
编辑: FWIW,我将其用于 FastAPI 应用程序。
编辑2: 对于我的第二个问题,我认为第一个替代方案更好,因为它包含架构中的长度要求(因此它在文档中)
你问了一个关于在 Pydantic 中使用
Field
和
constr
的区别的有趣问题。两者都可以用来定义字段的约束条件,但它们在适用性和最佳实践方面有所不同。
Field
与
constr
用于基本验证
你完全正确,在你的第一个例子中,
Field(..., min_length=1)
和
constr(min_length=1)
在功能上是等效的。它们都强制执行了
name
字段不能为空字符串。
通常,建议将
constr
用于简单类型约束,因为它更简洁易读。
Field
更强大,当你需要使用
constr
不支持的其他选项(如
regex
、
example
或自定义验证函数)时,应该使用它。
非空字符串列表的验证
对于你的第二个问题(验证非空字符串列表),第一个选项使用
List[constr(min_length=1)]
更简洁,并且在模型定义本身中表达了验证逻辑,使其更易理解和记录。
第二个选项,使用
@validator
,虽然有效,但引入了更冗长的代码,并且验证逻辑与模型定义分离。
因此,对于大多数情况,首选使用
List[constr(min_length=1)]
的方法。
关于 FastAPI 的注意事项
你提到你正在使用 FastAPI。值得注意的是,FastAPI 利用 Pydantic 进行数据验证和文档。使用
constr
或具有描述性
Field
设置将使 FastAPI 在你的 API 文档中包含这些约束,从而使客户端更容易理解你的 API 的预期数据结构。
总之:
-
对于简单的类型约束,如
min_length
,首选constr
以提高可读性和简洁性。 -
当需要更复杂的验证或需要额外的
Field
特性时,请使用Field
。 -
对于非空字符串列表,
List[constr(min_length=1)]
比使用@validator
的自定义函数更简洁,更可取。
通过遵循这些指南,你可以编写出更可维护、自文档化的 Pydantic 模型来满足你的 FastAPI 应用程序的需求。
标签:python,fastapi,python-typing,pydantic From: 70383316