Flask 如何验证前端传过来的数据

查看 191|回复 10
作者:XueXianqi   
大家在用 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=[, ])
如何提示给前端到底错在哪里(之前手动校验的时候,是可以直接抛出指定异常,比如说 raise ValueError("假期类型错误,只能为 XXX 、XXX"))
也许 Pydantic 是很好,但是我好像不太会用,有没有大佬有正确的打开方式,或者说其他可以拿来就用的第三方库

Enum, pydantic, holiday, flask

BingoXuan   
try except 捕获 ValidationError ,然后返回 http code 400 和错误信息
高级一点就是自己写个 middleware 处理
maocat   
flask_marshmallow 很久之前用的了,不知道现在啥情况了
raptor   
flask-restx 试试?
lambdaq   
> Django 的 Forms 和 DRF 的 Serializer 都很香
说明你们数据校验需求真的很简单。
maocat   
#2 看样子还在更新 https://github.com/marshmallow-code/marshmallow
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': [
,
,
],
},
},
],
)
具体的错误信息应该如何解析呢(比如说这里只有英文内容的 msg ,有类似于 Django 设置国际化,转换成中文的配置么)
XueXianqi
OP
  
@lambdaq Django 的 Forms 只是初学 Django 的时候觉得好用,实际业务中是 用的 DRF 的 Serializer ,还是有很多自定义的 validator 的,不可能单纯地用原有的校验数据类型、长度等
mikurasa   
https://flask-restx.readthedocs.io/en/latest/parsing.html 解君愁
Baloneo   
```
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')
```
您需要登录后才可以回帖 登录 | 立即注册

返回顶部