大家在用 Flask 的时候,是如何校验数据的类型和值的?
我之前用过 Django + DRF ,Django 的 Forms 和 DRF 的 Serializer 都很香,校验和处理数据
但是 Flask 有点让我发愁,手动用大量的 if 看起来费时费力,不太美观
有没有现成的第三方库可以用的,并且可以自定义抛出异常的类型并捕获
之前看过一些 FastAPI 用的 Pydantic 还有 Marshmallow
Pydantic 抛出的异常可能我不知道正确的打开方式,不太会用
比如说:
from enum import Enum
from pydantic import (
BaseModel,
Field,
)
class HolidayTypeEnum(str, Enum):
ANNUAL_LEAVE = "annual_leave"
SICK_LEAVE = "sick_leave"
class Holiday(BaseModel):
holiday_name: str = Field(..., description="请填写假期名称")
holiday_type: HolidayTypeEnum = Field(..., description="请填写假期类型")
data = {
"holiday_name": "年假",
"holiday_type": "annual_leave1",
}
holiday = Holiday(**data)
抛出的异常是:
pydantic.error_wrappers.ValidationError: 1 validation error for Holiday
holiday_type
value is not a valid enumeration member; permitted: 'annual_leave', 'sick_leave' (type=type_error.enum; enum_values=[<HolidayTypeEnum.ANNUAL_LEAVE: 'annual_leave'>, <HolidayTypeEnum.SICK_LEAVE: 'sick_leave'>])
如何提示给前端到底错在哪里(之前手动校验的时候,是可以直接抛出指定异常,比如说 raise ValueError("假期类型错误,只能为 XXX 、XXX")
)
也许 Pydantic 是很好,但是我好像不太会用,有没有大佬有正确的打开方式,或者说其他可以拿来就用的第三方库
1
BingoXuan 2023-09-06 09:24:48 +08:00
try except 捕获 ValidationError ,然后返回 http code 400 和错误信息
高级一点就是自己写个 middleware 处理 |
2
maocat 2023-09-06 09:33:59 +08:00
flask_marshmallow 很久之前用的了,不知道现在啥情况了
|
3
raptor 2023-09-06 09:34:31 +08:00
flask-restx 试试?
|
4
lambdaq 2023-09-06 09:34:39 +08:00
> Django 的 Forms 和 DRF 的 Serializer 都很香
说明你们数据校验需求真的很简单。 |
5
maocat 2023-09-06 09:35:27 +08:00
|
6
XueXianqi OP @BingoXuan
我看了一下捕获到的 ValidationError ,内容是这样的: ValidationError( model='Holiday', errors=[ { 'loc': ( 'holiday_type', ), 'msg': "value is not a valid enumeration member; permitted: 'annual_leave', 'sick_leave'", 'type': 'type_error.enum', 'ctx': { 'enum_values': [ <HolidayTypeEnum.ANNUAL_LEAVE: 'annual_leave'>, <HolidayTypeEnum.SICK_LEAVE: 'sick_leave'>, ], }, }, ], ) 具体的错误信息应该如何解析呢(比如说这里只有英文内容的 msg ,有类似于 Django 设置国际化,转换成中文的配置么) |
7
XueXianqi OP @lambdaq Django 的 Forms 只是初学 Django 的时候觉得好用,实际业务中是 用的 DRF 的 Serializer ,还是有很多自定义的 validator 的,不可能单纯地用原有的校验数据类型、长度等
|
8
mikurasa 2023-09-06 09:47:47 +08:00
|
9
Baloneo 2023-09-06 09:51:32 +08:00
```
def validate_schema(schema_class): assert issubclass(schema_class, Schema) # Marshmallow def decorator(view_func): @functools.wraps(view_func) def inner(*args, **kwargs): if request.method == "GET": form_data = request.args else: form_data = request.json try: data = schema_class().load(form_data) _request_ctx_stack.top.schema_data = data except ValidationError as e: return error_json( ResponseCode.ERROR, parse_err_messages(e), data=e.messages ) return view_func(*args, **kwargs) return inner return decorator @validate_schema(val.PostTestSchema) def api_test(): device_id = current_schema_data.get('device_id') ``` |
10
cyber2077 2023-09-06 09:52:05 +08:00 via Android
用 wtforms
|
11
BingoXuan 2023-09-06 10:12:51 +08:00
@XueXianqi
pydantic 有例子说明怎么获取具体的 validation error https://docs.pydantic.dev/latest/errors/validation_errors/ 国际化要看项目怎么做国际化了,最朴素就是自定义错误,自家处理国际化 |
12
rexyan 2023-09-06 10:47:47 +08:00
voluptuous + 装饰器
|
13
zcf0508 2023-09-06 10:59:52 +08:00 via Android
试试 apiflask
|
14
911061873 2023-09-06 14:28:00 +08:00
|
15
dayeye2006199 2023-09-06 23:25:31 +08:00
|
16
yudengqing 2023-09-07 09:24:53 +08:00 via iPhone
用 wtform 吧,也很方便
|