FastAPI教程-路径参数-Query()参数校验(传统用法)

提出问题

开发时,要对传入的数据做校验,如:

  • 传入姓名,要校验长度,如:最小2个字符,最长20个字符
  • 传入年龄,要校验最小值大于1岁,最大值小于120岁

例子

根据姓名查询学生,要求学生姓名必须是2-3个字符

from fastapi import FastAPI

app = FastAPI()

@app.get('/student')
async def get_student(name: str):
    if len(name)<2:
        return {
            "msg":"姓名不能少于2个字符"
        }
    elif len(name)>3:
        return {
            "msg":"姓名不能多于3个字符"
        }
    if name == '李雷':
        student = {
            'name': '李雷',
            'age': 21,
        }
    else:
        student = {
            'message': '没有此学号的学生',
        }
    return student

分析

每次需要写校验判断,太复杂

解决

使用 fastapi 的 Query() 参数校验

介绍

Query() 用于 查询参数(URL ?key=value),做校验、写接口文档。

对查询参数做:最小值、最大值、正则、描述、别名等校验。

注意

Query 只作用于 查询参数,不能用于路径参数;路径参数用 Path()。

常用参数

第一个参数

是查询参数的 默认值,官方推荐必须写,无默认值写 ...(省略号用法详见 链接)

提示:不传第一个参数也可行,底层做了兼容处理,但旧版用法推荐传值

其他参数

如下表格:

参数 类型 作用 适用类型 备注
ge float 或 None 大于等于(greater or equal) int / float ge=1 → 值 ≥1
gt float 或 None 大于(greater than) int / float gt=1 → 值 >1
le float 或 None 小于等于(less or equal) int / float le=100 → 值 ≤100
lt float 或 None 小于(less than) int / float lt=100 → 值 <100
min_length int 或 None 字符串最小长度 str 包含边界,min_length=2最少2个字符
max_length int 或 None 字符串最大长度 str 包含边界,max_length=10最多10个字符
pattern str 或 None 正则匹配表达式 str 原始正则字符串,例如 r"^A\d{4}$";不匹配返回422
title str 或 None OpenAPI文档参数标题 全部类型 仅接口文档显示,不参与校验
description str 或 None OpenAPI详细描述 全部类型 仅接口文档,不会改变报错提示
example Any 单个示例值 全部类型 文档展示一个样例
examples dict或list 或 None 多组示例 全部类型 可以传列表 [1,10];也可以传OpenAPI标准dict格式
deprecated bool 或 None 标记参数废弃 全部类型 deprecated=True,接口文档划横线提示废弃,不阻止请求

案例:重新上面的功能

@app.get('/student')
async def get_student(name: str=Query(...,min_length=2,max_length=3)):
    if name == '李雷':
        student = {
            'name': '李雷',
            'age': 21,
        }
    else:
        student = {
            'message': '没有此学号的学生',
        }
    return student

测试:长度过短

访问:http://127.0.0.1:8000/student/李,浏览器显示如下:

{
    "detail": [
        {
            "type": "string_too_short",
            "loc": [
                "query",
                "name"
            ],
            "msg": "String should have at least 2 characters",
            "input": "李",
            "ctx": {
                "min_length": 2
            }
        }
    ]
}

解释:

  • type:错误类型,string_too_short,即:字符串太短
  • loc...query...name:表示查询参数 name 报错了
  • msg:错误信息,翻译过来是:字符串至少是 2 个字符
  • input:表示当前传入的参数是 李
  • ctx:表示该参数最小长度是 2

测试:长度过长

访问:http://127.0.0.1:8000/student/lili,浏览器显示如下:

{
    "detail": [
        {
            "type": "string_too_long",
            "loc": [
                "path",
                "name"
            ],
            "msg": "String should have at most 3 characters",
            "input": "lili",
            "ctx": {
                "max_length": 3
            }
        }
    ]
}

解释:

  • type:错误类型,string_too_long,即:字符串太长
  • loc...query...name:表示查询参数 name 报错了
  • msg:错误信息,翻译过来是:字符串至多是 3 个字符
  • input:表示当前传入的参数是 lili
  • ctx:表示该参数最大长度是 3

测试成功

访问:http://127.0.0.1:8000/student/李雷,浏览器显示如下:

{
    "name": "李雷",
    "age": 21
}

例子:校验数字

校验年龄,最小值大于10岁,最大值小于120岁

from fastapi import FastAPI,Path

app = FastAPI()

@app.get('/student')
async def get_student(age: int=Query(...,ge=10,le=120)):

    return {'msg': f'年龄{age}'}

测试:年龄过小

访问:http://127.0.0.1:8000/student?age=9,浏览器显示如下:

{
    "detail": [
        {
            "type": "greater_than_equal",
            "loc": [
                "path",
                "age"
            ],
            "msg": "Input should be greater than or equal to 10",
            "input": "9",
            "ctx": {
                "ge": 10
            }
        }
    ]
}

解释:

  • type:错误类型,greater_than_equal,即:大于等于
  • loc...query...age:表示查询参数 age 报错了
  • msg:错误信息,翻译过来是:输入应该大于等于 10
  • input:表示当前传入的参数是 9
  • ctx:表示该参数应大于等于 10

测试:年龄过大

访问:http://127.0.0.1:8000/student?age=121,浏览器显示如下:

{
    "detail": [
        {
            "type": "less_than_equal",
            "loc": [
                "path",
                "age"
            ],
            "msg": "Input should be less than or equal to 120",
            "input": "121",
            "ctx": {
                "le": 120
            }
        }
    ]
}

解释:

  • type:错误类型,less_than_equal,即:小于等于
  • loc...query...age:表示查询参数 age 报错了
  • msg:错误信息,翻译过来是:输入应该小于等于 120
  • input:表示当前传入的参数是 121
  • ctx:表示该参数应小于等于 120

自动文档

访问 /docs,所有Query参数会自动生成表单、校验提示、描述、废弃标记。


原文出处:/show_1GW3r9O8pwGa.html