可选参数
上一篇文章讲过查询参数可以不是必传的,可以是可选参数
from fastapi import FastAPI from typing import Optional import uvicorn app = FastAPI() # 必传参数+可选参数 @app.get("/items") async def read_item(item_id: str, name: Optional[str] = None): return {"item_id": item_id, "name": name} if __name__ == "__main__": uvicorn.run(app="4_get_valiation:app", host="127.0.0.1", port=8080, debug=True, reload=True)
postman 请求结果
可选其实也是一种校验
Query
为了对查询参数进行额外的校验,可以导入 Query 库
Query 支持多种校验
可选参数有默认值+长度最大为 10
# 需要先导入 Query 库 from fastapi import Query @app.get("/itmes/") async def read_items(name: Optional[str] = Query(default=None, max_length=10)): results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]} if name: results.update({"name": name}) return results
不传 name 的请求结果
传了 name,校验成功的请求结果
name 长度大于 10,校验失败的请求结果
友好的错误提示啊!!直接说清楚哪个字段长度不满足了...
name: Optional[str] = Query(None) 等价于
name: Optional[str] = None
Optional 的作用
为了让 IDE 更好的支持智能提示
一个参数多个校验
# 多条校验 @app.get("/items/twice") async def read_items(name: Optional[str] = Query(default=None, min_length=3, max_length=10)): return {"name": name}
校验成功的请求结果
name 长度小于 3,校验失败的请求结果
添加正则表达式校验
# 正则表达式 @app.get("/items/regular") async def read_items( name: Optional[str] = Query( default=None, min_length=3, max_length=10, regex="^小.*菠萝$" )): return {"name": name}
校验成功的请求结果
name 不满足正则,校验失败的请求结果
查看 Swagger API 文档
正则表达式教程
https://www.cnblogs.com/poloyy/category/1796055.html
必传参数+长度最小为 3
不使用 Query 时,查询参数怎么必传?
不指定默认值就行
name: str
当使用 Query 时,查询参数怎么必传?
Query 默认值参数 default 是必传的,传了默认值不就变成可选参数了吗,那怎么办呢?
# 必传参数 @app.get("/items/require") async def read_items(name: Optional[str] = Query(default=..., max_length=10)): return {"name": name}
只需要将 ... 赋值给 default 参数,FastAPI 就会知道这个参数是必传的
校验成功的请求结果
没有传必传参数,校验失败的请求结果
因为是必传参数,不传则报错!
查看 Swagger API 文档
大大的 required 标识!代表必传哦!
List 类型的查询参数
使用 Query 时,可以指定查询参数的类型为 List,即一个参数可以接收多个值
from typing import List # List[str] @app.get("/list") async def read_item(address: Optional[List[str]] = Query([], max_length=2)): return {"address": address}
没有传参的请求结果
取 address 默认值 []
正确传参的请求结果
设置了校验 max_length=2,但传了三个 address 也正常,证明这个 max_length 的校验对数组长度并不生效
校验失败的请求结果
看来 max_length 校验仍然会对数组里面的字符串生效!
查看 Swagger API 文档
List 类型的查询参数有多个默认值
@app.get("/list/default") async def read_item(address: Optional[List[str]] = Query(["广州", "深圳"])): return {"address": address}
不传参的请求结果
元数据
Query 可以添加元数据相关信息,这些信息将包含在生成的 OpenAPI 中,并由文档用户界面和外部工具使用
四种元数据参数
# 别名 alias: Optional[str] = None # 标题 title: Optional[str] = None # 描述 description: Optional[str] = None # 是否弃用 deprecated: Optional[bool] = None
实际代码
# 元数据 @app.get("/items/all") async def read_items( name: Optional[str] = Query( default=None, min_length=2, max_length=50, regex="^菠萝$", alias="name_alias_query", title="标题", description="很长很长的描述", deprecated=True, ) ): return {"name": name}
不使用 alias 进行传参的请求结果
当做不存在的查询参数处理
用 alias 进行传参的请求结果
定义了 alias,记得要用 alias 进行传参
查看 Swagger API 文档
- title 字段并不会显示在这里,只会显示在 JSON Schema 中
- 而 JSON Schema 只有请求参数方式为 Request Body 才会显示,这里是查询参数,所以并没有 JSON Schema 这一说;后面的文章会详细介绍
总结
限定于字符串的校验:
- min_length
- max_length
- regex
Path
除了可以给查询参数添加额外的校验,也可以给路径参数添加额外的校验