第 2 章 BaseModel 与模型对象
上一章已经用 BaseModel 校验过文章数据。这次我们把几个容易混在一起的名字分清楚:ArticleCreate 是模型类,article 是什么?它和原始字典 data 又有什么区别?
本章学习目标
这章要把模型真正用起来:自己定义一个基础模型,分清模型类、模型对象和普通字典,并知道字段名、类型注解各管什么。随后用 model_validate() 校验字典;遇到常见错误时,也能判断问题出在哪一步。
从模型类到模型对象
继续使用文章数据:
data = {
"title": "Pydantic 入门",
"content": "这是一篇文章",
"views": 100,
}字典里有一篇具体文章,但它没有说明文章创建数据需要哪些字段、各字段是什么类型。我们先把结构写进模型,再把这份数据交给它。
每个完整代码块都可以复制到本地 .code/main.py。切换示例时覆盖这个文件,然后在 .code 目录运行 uv run python main.py。
模型类描述数据结构
BaseModel 是 Pydantic 提供的基础类。继承它以后,模型才能根据字段声明校验输入、进行基础类型转换,并在成功时生成模型对象。
字段写成 字段名: 类型:左边是字段名,右边是类型要求。比如 title: str 表示标题是字符串,views: int 表示阅读量是整数。类型注解也会参与 Pydantic 的输入校验。
先只定义模型,暂时不传入数据:
from pydantic import BaseModel
class ArticleCreate(BaseModel):
title: str
content: str
views: int运行:
uv run python main.py程序正常结束,没有输出。这是预期结果:ArticleCreate 现在只描述文章数据的结构,还没有对应某一篇具体文章。
从字典生成模型对象
data 仍是普通字典。调用 ArticleCreate.model_validate(data) 后,Pydantic 会检查必需字段是否齐全、输入值是否符合类型要求;校验通过才会返回模型对象 article。
ArticleCreate -> 模型类,描述数据结构
data -> 普通字典,保存原始输入
article -> 模型对象,保存校验后的数据把字典交给模型:
from pydantic import BaseModel
class ArticleCreate(BaseModel):
title: str
content: str
views: int
data = {
"title": "Pydantic 入门",
"content": "这是一篇文章",
"views": 100,
}
article = ArticleCreate.model_validate(data)
print(article)
print(article.title)
print(article.content)
print(article.views)运行:
uv run python main.py可能看到类似输出:
title='Pydantic 入门' content='这是一篇文章' views=100
Pydantic 入门
这是一篇文章
100默认情况下,模型未声明的额外字段会被忽略。必需字段名如果写错,比如输入只有 view,views 仍然缺失,校验会失败。
模型对象与普通字典
现在用同一份文章数据分别通过字典和模型对象取标题:
from pydantic import BaseModel
class ArticleCreate(BaseModel):
title: str
content: str
views: int
data = {
"title": "Pydantic 入门",
"content": "这是一篇文章",
"views": 100,
}
article = ArticleCreate.model_validate(data)
print("字典访问标题:", data["title"])
print("模型对象访问标题:", article.title)
print("字典本身:", data)
print("模型对象:", article)运行:
uv run python main.py可能看到类似输出:
字典访问标题: Pydantic 入门
模型对象访问标题: Pydantic 入门
字典本身: {'title': 'Pydantic 入门', 'content': '这是一篇文章', 'views': 100}
模型对象: title='Pydantic 入门' content='这是一篇文章' views=100字典用 data["title"] 取值,模型对象用 article.title 取值。model_validate() 返回新的模型对象,data 本身还是字典;后续代码可以使用通过校验的 article。
输入校验错误
模型要求 views: int,输入却是无法转换为整数的 "abc"。这种情况下,model_validate() 会抛出 ValidationError,不会返回模型对象。下面的代码捕获错误,让程序继续运行:
from pydantic import BaseModel, ValidationError
class ArticleCreate(BaseModel):
title: str
content: str
views: int
bad_data = {
"title": "Pydantic 入门",
"content": "这是一篇文章",
"views": "abc",
}
try:
article = ArticleCreate.model_validate(bad_data)
print(article)
except ValidationError as e:
print("数据校验失败")
print(e)运行:
uv run python main.py错误信息可能还会列出输入值和错误类型;这里先看字段名和核心原因:
数据校验失败
1 validation error for ArticleCreate
views
Input should be a valid integer模型要求整数,"abc" 无法转换。程序进入 except ValidationError 后,就不会继续使用这份错误数据。
常见模型使用错误
这几种问题分别发生在模型定义、输入校验和对象访问时。出错时先看代码停在哪一步。
忘记继承 BaseModel:
class ArticleCreate:
title: str
content: str
views: int这是普通类,不是 Pydantic 模型。调用 ArticleCreate.model_validate(data) 时会发现类上没有这个方法。
字段没有类型注解:
class ArticleCreate(BaseModel):
title = "Pydantic 入门"
content = "这是一篇文章"
views = 100模型字段要写成 字段名: 类型。上面的写法会在定义类时触发 PydanticUserError,还没有进入输入校验。
必需字段名写错:模型要求 views: int,输入却写成 view:
"view": 100默认配置会忽略未知字段 view,同时发现必需字段 views 缺失,因此校验失败。
访问不存在的字段:
print(article.author)如果模型里没有 author,访问 article.author 会触发 AttributeError。这不是输入校验错误,而是访问了模型中不存在的属性。
完整校验流程
最后让正确输入和错误输入走一遍完整流程:先校验并访问模型对象,再捕获不符合要求的数据。
from pydantic import BaseModel, ValidationError
class ArticleCreate(BaseModel):
title: str
content: str
views: int
data = {
"title": "Pydantic 入门",
"content": "这是一篇文章",
"views": 100,
}
article = ArticleCreate.model_validate(data)
print("=== 校验成功后的模型对象 ===")
print(article)
print("文章标题:", article.title)
print("文章内容:", article.content)
print("阅读量:", article.views)
bad_data = {
"title": "Pydantic 入门",
"content": "这是一篇文章",
"views": "abc",
}
try:
bad_article = ArticleCreate.model_validate(bad_data)
print(bad_article)
except ValidationError as e:
print("=== 错误数据校验失败 ===")
print(e)运行:
uv run python main.py运行后先看到正确文章的标题、内容和阅读量,随后看到错误数据在 views 字段上的校验失败:
定义模型类
↓
准备普通字典
↓
调用 model_validate()
├─ 成功:得到模型对象,通过属性访问字段
└─ 失败:捕获 ValidationError,处理错误输入本章小结
ArticleCreate 定义结构,data 是原始字典;model_validate() 校验通过,才会得到 article 这个模型对象。字段少了类型注解、输入没通过校验、访问了不存在的属性,看起来都像“报错”,却发生在不同阶段。排查时先分清阶段。