gpt4 book ai didi

python - fastapi表单数据与pytantic模型

转载 作者:行者123 更新时间:2023-12-03 13:43:26 31 4
gpt4 key购买 nike

我正在尝试从html表单提交数据,并使用pydantic模型对其进行验证。
使用此代码

from fastapi import FastAPI, Form
from pydantic import BaseModel
from starlette.responses import HTMLResponse


app = FastAPI()

@app.get("/form", response_class=HTMLResponse)
def form_get():
return '''<form method="post">
<input type="text" name="no" value="1"/>
<input type="text" name="nm" value="abcd"/>
<input type="submit"/>
</form>'''


class SimpleModel(BaseModel):
no: int
nm: str = ""

@app.post("/form", response_model=SimpleModel)
def form_post(form_data: SimpleModel = Form(...)):
return form_data

我如何通过http状态 422无法处理的实体得到错误

{"detail":[{"loc":["body","form_data"],"msg":"field required","type":"value_error.missing"}]}



等效的curl命令(由firfox生成)为

curl 'http://localhost:8001/form' -H 'Content-Type: application/x-www-form-urlencoded' --data 'no=1&nm=abcd'



这里的请求正文包含 no=1&nm=abcd
我究竟做错了什么?

最佳答案

我找到了可以帮助我们将FastAPI表单也用作pydantic的解决方案:)
我的代码:

class AnyForm(BaseModel):
any_param: str
any_other_param: int = 1

@classmethod
def as_form(
cls,
any_param: str = Form(...),
any_other_param: int = Form(1)
) -> AnyForm:
return cls(any_param=any_param, any_other_param=any_other_param)

@router.post('')
async def any_view(form_data: AnyForm = Depends(AnyForm.as_form)):
...
它像往常一样大张旗鼓地显示
我认为,它可以写得更通用,也许我会返回并编辑答案。
[更新]
我已经把它写成装饰器了
import inspect
from typing import Type

from fastapi import Form
from pydantic import BaseModel
from pydantic.fields import ModelField

def as_form(cls: Type[BaseModel]):
new_parameters = []

for field_name, model_field in cls.__fields__.items():
model_field: ModelField # type: ignore

if not model_field.required:
new_parameters.append(
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Form(model_field.default),
annotation=model_field.outer_type_,
)
)
else:
new_parameters.append(
inspect.Parameter(
model_field.alias,
inspect.Parameter.POSITIONAL_ONLY,
default=Form(...),
annotation=model_field.outer_type_,
)
)

async def as_form_func(**data):
return cls(**data)

sig = inspect.signature(as_form_func)
sig = sig.replace(parameters=new_parameters)
as_form_func.__signature__ = sig # type: ignore
setattr(cls, 'as_form', as_form_func)
return cls
用法看起来像
class Test1(BaseModel):
a: str
b: int


@as_form
class Test(BaseModel):
param: str
test: List[Test1]
test1: Test1
b: int = 1
a: str = '2342'


@router.post('/me', response_model=Test)
async def me(request: Request, form: Test = Depends(Test.as_form)):
return form

关于python - fastapi表单数据与pytantic模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60127234/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com