8 changed files with 369 additions and 1 deletions
@ -0,0 +1,42 @@ |
|||||
|
from pydantic import BaseModel |
||||
|
from fastapi import FastAPI, Form, Request |
||||
|
from fastapi.responses import HTMLResponse |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
from jinja2 import DictLoader, Environment |
||||
|
|
||||
|
class MyModel(BaseModel): |
||||
|
checkbox: bool = True |
||||
|
|
||||
|
form_template = """ |
||||
|
<form action="/form" method="POST"> |
||||
|
{% for field_name, field in model.model_fields.items() %} |
||||
|
<p> |
||||
|
<label for="{{ field_name }}">{{ field_name }}</label> |
||||
|
{% if field.annotation.__name__ == "bool" %} |
||||
|
<input type="checkbox" name="{{field_name}}" |
||||
|
{% if field.default %} |
||||
|
checked="checked" |
||||
|
{% endif %} |
||||
|
> |
||||
|
{% else %} |
||||
|
<input name="{{ field_name }}"> |
||||
|
{% endif %} |
||||
|
</p> |
||||
|
{% endfor %} |
||||
|
<button type="submit">Submit</button> |
||||
|
</form> |
||||
|
""" |
||||
|
loader = DictLoader({"form.html": form_template}) |
||||
|
templates = Jinja2Templates(env=Environment(loader=loader)) |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/form", response_class=HTMLResponse) |
||||
|
async def show_form(request: Request): |
||||
|
return templates.TemplateResponse( |
||||
|
request=request, name="form.html", context={"model": MyModel} |
||||
|
) |
||||
|
|
||||
|
@app.post('/form') |
||||
|
async def submit_form(data: MyModel = Form()) -> MyModel: |
||||
|
return data |
@ -0,0 +1,44 @@ |
|||||
|
from typing import Annotated |
||||
|
|
||||
|
from pydantic import BaseModel |
||||
|
from fastapi import FastAPI, Form, Request |
||||
|
from fastapi.responses import HTMLResponse |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
from jinja2 import DictLoader, Environment |
||||
|
|
||||
|
class MyModel(BaseModel): |
||||
|
checkbox: bool = True |
||||
|
|
||||
|
form_template = """ |
||||
|
<form action="/form" method="POST"> |
||||
|
{% for field_name, field in model.model_fields.items() %} |
||||
|
<p> |
||||
|
<label for="{{ field_name }}">{{ field_name }}</label> |
||||
|
{% if field.annotation.__name__ == "bool" %} |
||||
|
<input type="checkbox" name="{{field_name}}" |
||||
|
{% if field.default %} |
||||
|
checked="checked" |
||||
|
{% endif %} |
||||
|
> |
||||
|
{% else %} |
||||
|
<input name="{{ field_name }}"> |
||||
|
{% endif %} |
||||
|
</p> |
||||
|
{% endfor %} |
||||
|
<button type="submit">Submit</button> |
||||
|
</form> |
||||
|
""" |
||||
|
loader = DictLoader({"form.html": form_template}) |
||||
|
templates = Jinja2Templates(env=Environment(loader=loader)) |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/form", response_class=HTMLResponse) |
||||
|
async def show_form(request: Request): |
||||
|
return templates.TemplateResponse( |
||||
|
request=request, name="form.html", context={"model": MyModel} |
||||
|
) |
||||
|
|
||||
|
@app.post('/form') |
||||
|
async def submit_form(data: Annotated[MyModel, Form()]) -> MyModel: |
||||
|
return data |
@ -0,0 +1,57 @@ |
|||||
|
from pydantic import BaseModel, ValidationInfo, model_validator |
||||
|
from fastapi import FastAPI, Form, Request |
||||
|
from fastapi.responses import HTMLResponse |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
from jinja2 import DictLoader, Environment |
||||
|
|
||||
|
class MyModel(BaseModel): |
||||
|
checkbox: bool = True |
||||
|
|
||||
|
@model_validator(mode="before") |
||||
|
def handle_defaults(cls, value: dict, info: ValidationInfo) -> dict: |
||||
|
# if this model is being used outside of fastapi, return normally |
||||
|
if info.context is None or 'fastapi_field' not in info.context: |
||||
|
return value |
||||
|
|
||||
|
# check if we are being validated from form input, |
||||
|
# and if so, treat the unset checkbox as False |
||||
|
field_info = info.context['fastapi_field'].field_info |
||||
|
is_form = type(field_info).__name__ == "Form" |
||||
|
if is_form and 'checkbox' not in value: |
||||
|
value['checkbox'] = False |
||||
|
return value |
||||
|
|
||||
|
|
||||
|
form_template = """ |
||||
|
<form action="/form" method="POST"> |
||||
|
{% for field_name, field in model.model_fields.items() %} |
||||
|
<p> |
||||
|
<label for="{{ field_name }}">{{ field_name }}</label> |
||||
|
{% if field.annotation.__name__ == "bool" %} |
||||
|
<input type="checkbox" name="{{field_name}}" |
||||
|
{% if field.default %} |
||||
|
checked="checked" |
||||
|
{% endif %} |
||||
|
> |
||||
|
{% else %} |
||||
|
<input name="{{ field_name }}"> |
||||
|
{% endif %} |
||||
|
</p> |
||||
|
{% endfor %} |
||||
|
<button type="submit">Submit</button> |
||||
|
</form> |
||||
|
""" |
||||
|
loader = DictLoader({"form.html": form_template}) |
||||
|
templates = Jinja2Templates(env=Environment(loader=loader)) |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/form", response_class=HTMLResponse) |
||||
|
async def show_form(request: Request): |
||||
|
return templates.TemplateResponse( |
||||
|
request=request, name="form.html", context={"model": MyModel} |
||||
|
) |
||||
|
|
||||
|
@app.post('/form') |
||||
|
async def submit_form(data: MyModel = Form()) -> MyModel: |
||||
|
return data |
@ -0,0 +1,59 @@ |
|||||
|
from typing import Annotated |
||||
|
|
||||
|
from pydantic import BaseModel, ValidationInfo, model_validator |
||||
|
from fastapi import FastAPI, Form, Request |
||||
|
from fastapi.responses import HTMLResponse |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
from jinja2 import DictLoader, Environment |
||||
|
|
||||
|
class MyModel(BaseModel): |
||||
|
checkbox: bool = True |
||||
|
|
||||
|
@model_validator(mode="before") |
||||
|
def handle_defaults(cls, value: dict, info: ValidationInfo) -> dict: |
||||
|
# if this model is being used outside of fastapi, return normally |
||||
|
if info.context is None or 'fastapi_field' not in info.context: |
||||
|
return value |
||||
|
|
||||
|
# check if we are being validated from form input, |
||||
|
# and if so, treat the unset checkbox as False |
||||
|
field_info = info.context['fastapi_field'].field_info |
||||
|
is_form = type(field_info).__name__ == "Form" |
||||
|
if is_form and 'checkbox' not in value: |
||||
|
value['checkbox'] = False |
||||
|
return value |
||||
|
|
||||
|
|
||||
|
form_template = """ |
||||
|
<form action="/form" method="POST"> |
||||
|
{% for field_name, field in model.model_fields.items() %} |
||||
|
<p> |
||||
|
<label for="{{ field_name }}">{{ field_name }}</label> |
||||
|
{% if field.annotation.__name__ == "bool" %} |
||||
|
<input type="checkbox" name="{{field_name}}" |
||||
|
{% if field.default %} |
||||
|
checked="checked" |
||||
|
{% endif %} |
||||
|
> |
||||
|
{% else %} |
||||
|
<input name="{{ field_name }}"> |
||||
|
{% endif %} |
||||
|
</p> |
||||
|
{% endfor %} |
||||
|
<button type="submit">Submit</button> |
||||
|
</form> |
||||
|
""" |
||||
|
loader = DictLoader({"form.html": form_template}) |
||||
|
templates = Jinja2Templates(env=Environment(loader=loader)) |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/form", response_class=HTMLResponse) |
||||
|
async def show_form(request: Request): |
||||
|
return templates.TemplateResponse( |
||||
|
request=request, name="form.html", context={"model": MyModel} |
||||
|
) |
||||
|
|
||||
|
@app.post('/form') |
||||
|
async def submit_form(data: Annotated[MyModel, Form()]) -> MyModel: |
||||
|
return data |
@ -0,0 +1,51 @@ |
|||||
|
from pydantic import BaseModel, model_validator |
||||
|
from fastapi import FastAPI, Form, Request |
||||
|
from fastapi.responses import HTMLResponse |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
from jinja2 import DictLoader, Environment |
||||
|
|
||||
|
class MyModel(BaseModel): |
||||
|
checkbox: bool = True |
||||
|
|
||||
|
@model_validator(mode="before") |
||||
|
def handle_defaults(cls, value: dict) -> dict: |
||||
|
# We can't tell if we're being validated by fastAPI, |
||||
|
# so we have to just YOLO this. |
||||
|
if 'checkbox' not in value: |
||||
|
value['checkbox'] = False |
||||
|
return value |
||||
|
|
||||
|
|
||||
|
form_template = """ |
||||
|
<form action="/form" method="POST"> |
||||
|
{% for field_name, field in model.model_fields.items() %} |
||||
|
<p> |
||||
|
<label for="{{ field_name }}">{{ field_name }}</label> |
||||
|
{% if field.annotation.__name__ == "bool" %} |
||||
|
<input type="checkbox" name="{{field_name}}" |
||||
|
{% if field.default %} |
||||
|
checked="checked" |
||||
|
{% endif %} |
||||
|
> |
||||
|
{% else %} |
||||
|
<input name="{{ field_name }}"> |
||||
|
{% endif %} |
||||
|
</p> |
||||
|
{% endfor %} |
||||
|
<button type="submit">Submit</button> |
||||
|
</form> |
||||
|
""" |
||||
|
loader = DictLoader({"form.html": form_template}) |
||||
|
templates = Jinja2Templates(env=Environment(loader=loader)) |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/form", response_class=HTMLResponse) |
||||
|
async def show_form(request: Request): |
||||
|
return templates.TemplateResponse( |
||||
|
request=request, name="form.html", context={"model": MyModel} |
||||
|
) |
||||
|
|
||||
|
@app.post('/form') |
||||
|
async def submit_form(data: MyModel = Form()) -> MyModel: |
||||
|
return data |
@ -0,0 +1,53 @@ |
|||||
|
from typing import Annotated |
||||
|
|
||||
|
from pydantic import BaseModel, model_validator |
||||
|
from fastapi import FastAPI, Form, Request |
||||
|
from fastapi.responses import HTMLResponse |
||||
|
from fastapi.templating import Jinja2Templates |
||||
|
from jinja2 import DictLoader, Environment |
||||
|
|
||||
|
class MyModel(BaseModel): |
||||
|
checkbox: bool = True |
||||
|
|
||||
|
@model_validator(mode="before") |
||||
|
def handle_defaults(cls, value: dict) -> dict: |
||||
|
# We can't tell if we're being validated by fastAPI, |
||||
|
# so we have to just YOLO this. |
||||
|
if 'checkbox' not in value: |
||||
|
value['checkbox'] = False |
||||
|
return value |
||||
|
|
||||
|
|
||||
|
form_template = """ |
||||
|
<form action="/form" method="POST"> |
||||
|
{% for field_name, field in model.model_fields.items() %} |
||||
|
<p> |
||||
|
<label for="{{ field_name }}">{{ field_name }}</label> |
||||
|
{% if field.annotation.__name__ == "bool" %} |
||||
|
<input type="checkbox" name="{{field_name}}" |
||||
|
{% if field.default %} |
||||
|
checked="checked" |
||||
|
{% endif %} |
||||
|
> |
||||
|
{% else %} |
||||
|
<input name="{{ field_name }}"> |
||||
|
{% endif %} |
||||
|
</p> |
||||
|
{% endfor %} |
||||
|
<button type="submit">Submit</button> |
||||
|
</form> |
||||
|
""" |
||||
|
loader = DictLoader({"form.html": form_template}) |
||||
|
templates = Jinja2Templates(env=Environment(loader=loader)) |
||||
|
|
||||
|
app = FastAPI() |
||||
|
|
||||
|
@app.get("/form", response_class=HTMLResponse) |
||||
|
async def show_form(request: Request): |
||||
|
return templates.TemplateResponse( |
||||
|
request=request, name="form.html", context={"model": MyModel} |
||||
|
) |
||||
|
|
||||
|
@app.post('/form') |
||||
|
async def submit_form(data: Annotated[MyModel, Form()]) -> MyModel: |
||||
|
return data |
Loading…
Reference in new issue