FastAPI教程-参数校验定义格式、汉化

提出问题

参数校验返回都是英文

默认参数校验,报错信息都是英文的,中国用户看不懂

返回格式与开发习惯不符合

改为更符合习惯的格式,如下:

{
    "code": 40001,
    "msg": "请求参数校验失败",
    "errors": [
        {
            "field": "path.name",
            "message": "输入内容太短,应该大于 2 个字符"
        }
    ]
}

创建异常处理文件

创建目录

在 main.py 文件的同级,创建 core 目录

创建文件

在 core 目录下创建 exceptions.py 文件,内容如下:

from fastapi import Request
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError

# 翻译字典:key是pydantic error type,稳定,版本升级不会变
VALIDATION_I18N = {
    "int_parsing": "请输入合法整数",
    "float_parsing": "请输入合法浮点数",
    "greater_than_equal": "输入应该大于等于 {ge}",
    "greater_than": "输入应该大于 {gt}",
    "less_than_equal": "输入应该小于等于 {le}",
    "less_than": "输入应该小于 {lt}",
    "string_too_short": "输入内容太短,应该大于 {min_length} 个字符",
    "string_too_long": "输入内容太长,应该小于 {max_length} 个字符",
    "string_pattern_mismatch": "格式不满足规则:{pattern}",
    "missing": "此字段必填",
    "bool_parsing": "只能传 true / false / 1 / 0",
}


async def validation_error_handler(request: Request, exc: RequestValidationError):
    err_list = []
    for err in exc.errors():
        field_path = ".".join(map(str, err["loc"]))
        err_type = err["type"]
        ctx = err.get("ctx", {})

        zh_msg = VALIDATION_I18N.get(err_type, f"参数错误:{err_type}")
        # 填充占位符,例如 {ge} {le} {pattern}
        try:
            zh_msg = zh_msg.format(**ctx)
        except KeyError:
            pass

        err_list.append({
            "field": field_path,
            "message": zh_msg
        })

    return JSONResponse(
        status_code=422,
        content={
            "code": 40001,       # 业务自定义错误码
            "msg": "请求参数校验失败",
            "errors": err_list
        }
    )

修改main.py

调用 app.add_exception_handler() 函数,将上面的 validation_error_handler 传进去:

from fastapi import FastAPI
from fastapi.params import Path
from core.exceptions import validation_error_handler
from fastapi.exceptions import RequestValidationError

app = FastAPI()
app.add_exception_handler(RequestValidationError, validation_error_handler)

完整代码

from fastapi import FastAPI
from fastapi.params import Path
from core.exceptions import validation_error_handler
from fastapi.exceptions import RequestValidationError

app = FastAPI()
app.add_exception_handler(RequestValidationError, validation_error_handler)

# @app.get('/student/{age}')
# async def update_student(age: int=Path(...,ge=10,le=120)):
#     print("age:", age)
#     return {'msg': '更新成功!'}


# @app.get('/student/{age}')
# async def update_student(age: int=Path(...,ge=10,le=120,description="年龄大于等于10岁,小于等于120岁")):
#     print("年龄:", age)
#     return {'msg': '更新成功!'}


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

测试

参数过短错误

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

{
    "code": 40001,
    "msg": "请求参数校验失败",
    "errors": [
        {
            "field": "path.name",
            "message": "输入内容太短,应该大于 2 个字符"
        }
    ]
}

参数过长错误

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

{
    "code": 40001,
    "msg": "请求参数校验失败",
    "errors": [
        {
            "field": "path.name",
            "message": "输入内容太长,应该小于 3 个字符"
        }
    ]
}

原文出处:/show_1GW3r2RrVd2H.html