|
1 | 1 | #请求体 |
2 | 2 |
|
3 | | -当你需要将数据从客户端(例如浏览器)发送给 API时,你将其作为「请求体」发送。 |
| 3 | +FastAPI 使用**请求体**从客户端(例如浏览器)向 API发送数据。 |
4 | 4 |
|
5 | | -**请求**体是客户端发送给 API 的数据。**响应**体是 API 发送给客户端的数据。 |
| 5 | +**请求体**是客户端发送给 API 的数据。**响应体**是 API 发送给客户端的数据。 |
6 | 6 |
|
7 | | -你的API几乎总是要发送**响应**体。但是客户端并不总是需要发送**请求**体。 |
| 7 | +API基本上总要发送**响应体**,但是客户端不一定发送**请求体**。 |
8 | 8 |
|
9 | | -我们使用 <ahref="https://pydantic-docs.helpmanual.io/"class="external-link"target="_blank">Pydantic</a>模型来声明**请求**体,并能够获得它们所具有的所有能力和优点。 |
| 9 | +使用 <ahref="https://pydantic-docs.helpmanual.io/"class="external-link"target="_blank">Pydantic</a>模型声明**请求体**,可以充分利用它的功能和优点。 |
10 | 10 |
|
11 | | -!!! info |
12 | | - 你不能使用`GET` 操作(HTTP 方法)发送请求体。 |
| 11 | +!!! info "说明" |
13 | 12 |
|
14 | | -要发送数据,你必须使用下列方法之一:`POST`(较常见)、`PUT`、`DELETE` 或 `PATCH`。 |
| 13 | +发送数据使用 `POST`(最常用)、`PUT`、`DELETE`、`PATCH` 等操作。 |
| 14 | + |
| 15 | +规范中没有定义使用 `GET` 发送请求体的操作,但不管怎样,FastAPI 也支持这种方式,只不过仅用于非常复杂或极端的用例。 |
| 16 | + |
| 17 | +我们不建议使用 `GET`,因此,在 Swagger UI 交互文档中不会显示有关 `GET` 的内容,而且代理协议也不一定支持 `GET`。 |
15 | 18 |
|
16 | 19 | ##导入 Pydantic 的`BaseModel` |
17 | 20 |
|
18 | | -首先,你需要从`pydantic` 中导入`BaseModel`: |
| 21 | +首先,从`pydantic` 中导入`BaseModel`: |
19 | 22 |
|
20 | | -```Python hl_lines="2" |
| 23 | +```Python hl_lines="4" |
21 | 24 | {!../../../docs_src/body/tutorial001.py!} |
22 | 25 | ``` |
23 | 26 |
|
24 | 27 | ##创建数据模型 |
25 | 28 |
|
26 | | -然后,将你的数据模型声明为继承自`BaseModel` 的类。 |
| 29 | +然后,把数据模型声明为继承自`BaseModel` 的类。 |
27 | 30 |
|
28 | | -使用标准的 Python类型来声明所有属性: |
| 31 | +使用 Python标准类型声明所有属性: |
29 | 32 |
|
30 | | -```Python hl_lines="5-9" |
| 33 | +```Python hl_lines="7-11" |
31 | 34 | {!../../../docs_src/body/tutorial001.py!} |
32 | 35 | ``` |
33 | 36 |
|
34 | | -和声明查询参数时一样,当一个模型属性具有默认值时,它不是必需的。否则它是一个必需属性。将默认值设为`None` 可使其成为可选属性。 |
| 37 | +包含默认值的模型属性与声明查询参数一样,不是必选的。没有默认值的模型属性是必选的。模型属性的默认值设为`None`,则为可选。 |
35 | 38 |
|
36 | | -例如,上面的模型声明了一个这样的 JSON「`object`」(或 Python`dict`): |
| 39 | +例如,上述模型声明了如下 JSON「对象」(也是 Python 的`dict`): |
37 | 40 |
|
38 | 41 | ```JSON |
39 | 42 | { |
|
44 | 47 | } |
45 | 48 | ``` |
46 | 49 |
|
47 | | -...由于`description` 和`tax` 是可选的(它们的默认值为`None`),下面的 JSON「`object`」也将是有效的: |
| 50 | +……由于`description` 和`tax` 是可选的(默认值为`None`),下面的 JSON「对象」也有效: |
48 | 51 |
|
49 | 52 | ```JSON |
50 | 53 | { |
|
53 | 56 | } |
54 | 57 | ``` |
55 | 58 |
|
56 | | -##声明为参数 |
| 59 | +##声明请求体参数 |
57 | 60 |
|
58 | | -使用与声明路径和查询参数的相同方式声明请求体,即可将其添加到「路径操作」中: |
| 61 | +使用与声明路径和查询参数相同的方式声明请求体,就可以把请求体添加至*路径操作*: |
59 | 62 |
|
60 | | -```Python hl_lines="16" |
| 63 | +```Python hl_lines="18" |
61 | 64 | {!../../../docs_src/body/tutorial001.py!} |
62 | 65 | ``` |
63 | 66 |
|
64 | | -...并且将它的类型声明为你创建的`Item` 模型。 |
| 67 | +……此处,请求体参数的类型为`Item` 模型。 |
65 | 68 |
|
66 | 69 | ##结果 |
67 | 70 |
|
68 | | -仅仅使用了 Python 类型声明,**FastAPI**将会: |
| 71 | +仅使用 Python 类型声明,**FastAPI**就可以: |
69 | 72 |
|
70 | | -*将请求体作为 JSON读取。 |
71 | | -*转换为相应的类型(在需要时)。 |
72 | | -* 校验数据。 |
73 | | -*如果数据无效,将返回一条清晰易读的错误信息,指出不正确数据的确切位置和内容。 |
74 | | -*将接收的数据赋值到参数`item` 中。 |
75 | | -*由于你已经在函数中将它声明为`Item` 类型,你还将获得对于所有属性及其类型的一切编辑器支持(代码补全等)。 |
76 | | -*为你的模型生成 <ahref="https://json-schema.org"class="external-link"target="_blank">JSON模式</a> 定义,你还可以在其他任何对你的项目有意义的地方使用它们。 |
77 | | -*这些模式将成为生成的 OpenAPI模式的一部分,并且被自动化文档 <abbrtitle="用户界面">UI</abbr> 所使用。 |
| 73 | +*以 JSON形式读取请求体; |
| 74 | +* (在需要时)把请求体转换为对应的类型; |
| 75 | +* 校验数据: |
| 76 | +*数据无效时返回错误信息,指出错误数据的确切位置和内容。 |
| 77 | +*把接收的数据赋值给参数`item`; |
| 78 | +*由于已经在函数中把请求体参数声明为`Item` 类型,还可以获得代码补全等对于所有属性及其类型的编辑器支持。 |
| 79 | +*为模型生成 <ahref="https://json-schema.org"class="external-link"target="_blank">JSONSchema</a> 定义,可以在项目中其他任何所需的位置使用; |
| 80 | +*这些概图作为 OpenAPI概图的部件,用于自动文档 <abbrtitle="用户界面">UI</abbr>。 |
78 | 81 |
|
79 | | -##自动化文档 |
| 82 | +##自动文档 |
80 | 83 |
|
81 | | -你所定义模型的 JSON模式将成为生成的 OpenAPI模式的一部分,并且在交互式 API文档中展示: |
| 84 | +模型的 JSON概图是 OpenAPI生产的概图部件,可显示在 API交互文档中: |
82 | 85 |
|
83 | | -<imgsrc="https://fastapi.tiangolo.com/img/tutorial/body/image01.png"> |
| 86 | +<imgsrc="/img/tutorial/body/image01.png"> |
84 | 87 |
|
85 | | -而且还将在每一个需要它们的*路径操作*的 API文档中使用: |
| 88 | +而且,还会用于 API文档中使用了概图的*路径操作*: |
86 | 89 |
|
87 | | -<imgsrc="https://fastapi.tiangolo.com/img/tutorial/body/image02.png"> |
| 90 | +<imgsrc="/img/tutorial/body/image02.png"> |
88 | 91 |
|
89 | | -##编辑器支持 |
| 92 | +##编辑器的支持 |
90 | 93 |
|
91 | | -在你的编辑器中,你会在函数内部的任意地方得到类型提示和代码补全(如果你接收的是一个`dict`而不是 Pydantic 模型,则不会发生这种情况): |
| 94 | +在编辑器中,函数内部均可使用类型提示、代码补全(如果接收的不是 Pydantic 模型,而是`dict`,就不会出现): |
92 | 95 |
|
93 | | -<imgsrc="https://fastapi.tiangolo.com/img/tutorial/body/image03.png"> |
| 96 | +<imgsrc="/img/tutorial/body/image03.png"> |
94 | 97 |
|
95 | | -你还会获得对不正确的类型操作的错误检查: |
| 98 | +还支持对错误类型操作的错误检查: |
96 | 99 |
|
97 | | -<imgsrc="https://fastapi.tiangolo.com/img/tutorial/body/image04.png"> |
| 100 | +<imgsrc="/img/tutorial/body/image04.png"> |
98 | 101 |
|
99 | | -这并非偶然,整个框架都是围绕该设计而构建。 |
| 102 | +这并非偶然,整个框架都是围绕这种操作精心设计的。 |
100 | 103 |
|
101 | | -并且在进行任何实现之前,已经在设计阶段经过了全面测试,以确保它可以在所有的编辑器中生效。 |
| 104 | +并且,在着手实现 FastAPI 之前的设计阶段,我们就已经进行了全面测试,以确保 FastAPI 可以获得所有编辑器的支持。 |
102 | 105 |
|
103 | | -Pydantic本身甚至也进行了一些更改以支持此功能。 |
| 106 | +甚至Pydantic也做出了改进,以支持此功能。 |
104 | 107 |
|
105 | | -上面的截图取自 <ahref="https://code.visualstudio.com"class="external-link"target="_blank">Visual Studio Code</a>。 |
| 108 | +虽然上面的截图取自 <ahref="https://code.visualstudio.com"class="external-link"target="_blank">Visual Studio Code</a>。 |
106 | 109 |
|
107 | | -但是在 <ahref="https://www.jetbrains.com/pycharm/"class="external-link"target="_blank">PyCharm</a>和绝大多数其他 Python编辑器中你也会获得同样的编辑器支持: |
| 110 | +但 <ahref="https://www.jetbrains.com/pycharm/"class="external-link"target="_blank">PyCharm</a>和大多数 Python编辑器也支持同样的功能: |
108 | 111 |
|
109 | | -<imgsrc="https://fastapi.tiangolo.com/img/tutorial/body/image05.png"> |
| 112 | +<imgsrc="/img/tutorial/body/image05.png"> |
| 113 | + |
| 114 | +!!! tip "提示" |
| 115 | + |
| 116 | +使用 <a href="https://www.jetbrains.com/pycharm/" class="external-link" target="_blank">PyCharm</a> 编辑器时,推荐 <a href="https://github.com/koxudaxi/pydantic-pycharm-plugin/" class="external-link" target="_blank">Pydantic PyCharm 插件</a>。 |
| 117 | + |
| 118 | +该插件用于改进 PyCharm 对 Pydantic 模型的支持,优化的功能如下: |
| 119 | + |
| 120 | +* 自动补全 |
| 121 | +* 类型检查 |
| 122 | +* 代码重构 |
| 123 | +* 查找 |
| 124 | +* 代码审查 |
110 | 125 |
|
111 | 126 | ##使用模型 |
112 | 127 |
|
113 | | -在函数内部,你可以直接访问模型对象的所有属性: |
| 128 | +在函数内部,可以直接访问模型对象的所有属性: |
114 | 129 |
|
115 | | -```Python hl_lines="19" |
| 130 | +```Python hl_lines="21" |
116 | 131 | {!../../../docs_src/body/tutorial002.py!} |
117 | 132 | ``` |
118 | 133 |
|
119 | 134 | ##请求体 + 路径参数 |
120 | 135 |
|
121 | | -你可以同时声明路径参数和请求体。 |
| 136 | +**FastAPI** 支持同时声明路径参数和请求体。 |
122 | 137 |
|
123 | | -**FastAPI**将识别出与路径参数匹配的函数参数应**从路径中获取**,而声明为 Pydantic模型的函数参数应**从请求体中获取**。 |
| 138 | +**FastAPI**可以识别出与路径参数匹配的,**要从路径中获取**的函数参数,以及声明为 Pydantic模型的,**要从请求体中获取**的函数参数。 |
124 | 139 |
|
125 | | -```Python hl_lines="15-16" |
| 140 | +```Python hl_lines="17-18" |
126 | 141 | {!../../../docs_src/body/tutorial003.py!} |
127 | 142 | ``` |
128 | 143 |
|
129 | 144 | ##请求体 + 路径参数 + 查询参数 |
130 | 145 |
|
131 | | -你还可以同时声明**请求体**、**路径参数**和**查询参数**。 |
| 146 | +**FastAPI** 还支持同时声明**请求体**、**路径参数**和**查询参数**。 |
132 | 147 |
|
133 | | -**FastAPI**会识别它们中的每一个,并从正确的位置获取数据。 |
| 148 | +**FastAPI**可以正确识别出这三种参数,并从正确的位置获取数据。 |
134 | 149 |
|
135 | | -```Python hl_lines="16" |
| 150 | +```Python hl_lines="18" |
136 | 151 | {!../../../docs_src/body/tutorial004.py!} |
137 | 152 | ``` |
138 | 153 |
|
139 | | -函数参数将依次按如下规则进行识别: |
| 154 | +函数参数按如下规则进行识别: |
| 155 | + |
| 156 | +-**路径**中声明了相同参数的参数,是路径参数 |
| 157 | +- 类型是(`int`、`float`、`str`、`bool` 等)**单类型**的参数,是**查询**参数 |
| 158 | +- 类型是**Pydantic 模型**的参数,是**请求体** |
| 159 | + |
| 160 | +!!! note "笔记" |
140 | 161 |
|
141 | | -* 如果在**路径**中也声明了该参数,它将被用作路径参数。 |
142 | | -* 如果参数属于**单一类型**(比如`int`、`float`、`str`、`bool` 等)它将被解释为**查询**参数。 |
143 | | -* 如果参数的类型被声明为一个**Pydantic 模型**,它将被解释为**请求体**。 |
| 162 | +因为默认值是 `=None`, FastAPI 可以识别出 `q` 是可选的。 |
| 163 | +
|
| 164 | +FastAPI 不使用 `Optional[str]` 中的 `Optional`, 但 `Optional` 可以让编辑器提供更好的支持,并检测错误。 |
144 | 165 |
|
145 | 166 | ##不使用 Pydantic |
146 | 167 |
|
147 | | -如果你不想使用 Pydantic 模型,你还可以使用**Body** 参数。请参阅文档[请求体 -多个参数:请求体中的单一值](body-multiple-params.md#singular-values-in-body){.internal-link target=_blank}。 |
| 168 | +即便不使用 Pydantic 模型,也可以使用**Body** 参数。请参阅[请求体 -多参数:请求体中的单值](body-multiple-params.md#singular-values-in-body){.internal-link target=\_blank}。 |