FastAPI教程-请求体参数-Field()参数校验(传统用法)

提出问题

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

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

例子

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

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()


# 定义请求体模型
class StudentCreate(BaseModel):
    name: str


@app.post('/student')
async def create_student(student: StudentCreate):
    if len(student.name) < 2:
        return {
            "msg": "姓名不能少于2个字符"
        }
    elif len(student.name) > 3:
        return {
            "msg": "姓名不能多于3个字符"
        }

    return {
        'msg': '添加成功',
        'data': student.model_dump()
    }

测试

访问 swagger:http://127.0.0.1:8000/docs

发数据:

{
  "name": "李"
}

结果如下:

分析

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

解决

使用 fastapi 的 Field() 参数校验

介绍

Field() 用于 请求体参数,做校验、写接口文档。

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

注意

Field 只作用于 请求体参数

常用参数

第一个参数

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

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

其他参数

如下表格:

参数 类型 作用 适用类型 备注
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,接口文档划横线提示废弃,不阻止请求

案例:重新上面的功能

# 定义请求体模型
class StudentCreate(BaseModel):
    name: str = Field(...,min_length=2,max_length=3)


@app.post('/student')
async def create_student(student: StudentCreate):
    return {
        'msg': '添加成功',
        'data': student.model_dump()
    }

测试:长度过短

访问swagger,发送数据:

{
  "name": "李"
}

结果如下:

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

解释:

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

测试:长度过长

访问swagger,发送数据:

{
  "name": "lili"
}

结果如下:

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

解释:

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

测试成功

访问swagger,发送数据:

{
  "name": "李雷"
}

结果如下:

{
  "msg": "添加成功",
  "data": {
    "name": "李雷"
  }
}

例子:校验数字

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

from fastapi import FastAPI
from pydantic import BaseModel, Field

app = FastAPI()


# 定义请求体模型
class StudentCreate(BaseModel):
    name: str = Field(...,min_length=2,max_length=3)
    age: int = Field(..., ge=10, le=120)


@app.post('/student')
async def create_student(student: StudentCreate):
    return {
        'msg': '添加成功',
        'data': student.model_dump()
    }

测试:年龄过小

访问swagger,发送数据:

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

结果如下:

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

解释:

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

测试:年龄过大

访问swagger,发送数据:

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

结果如下:

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

解释:

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

原文出处:/show_1GW3rRgcxiRz.html