How do I submit the value
selected from an HTML dropdown list using FastAPI in the backend and HTML/Jinja2 template in the frontend?
Here is my code for the app so far:
from fastapi import FastAPI, Request, Form
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory="templates/")
@app.get('/')
def read_form():
return 'hello world'
@app.get("/form")
def form_post(request: Request):
result = "Select your name"
return templates.TemplateResponse('form.html', context={'request': request, 'result': result})
@app.post("/form")
def form_post(request: Request, result = Form(...)):
return templates.TemplateResponse('form.html', context={'request': request, 'result': result})
Here is the HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Sample Form</title>
</head>
<body>
<form method="post">
<select name="names" id="names">
<option value="n1">Name 1</option>
<option value="n2">Name 2</option>
<option value="n3">Name 3</option>
<option value="n5">Name 4</option>
</select>
<input type="submit" value="Submit">
</form>
<p>Result: {{ result }}</p>
</body>
</html>
Here is the error message:
{"detail":[{"loc":["body","result"],"msg":"field required","type":"value_error.missing"}]}
The goal is to select a name
, then click submit
, and finally, have it displayed below.
def form_post(request: Request, names: str = Form(...)):
- you can then include this as "result": names
to your template. Where num
is from I have no idea about, since you haven't referenced that parameter in your included code. You need to make sure to include the action
attribute in the form, which specifies where to send the form-data
when a form is submitted (see W3schools <form>
tag docs as well). Also, in the <select>
element that is used to create the drop-down list, make sure to use the same name
used to define the Form
parameter in your endpoint. As per W3schools <select>
tag docs:
The
name
attribute is needed to reference the form data after the form is submitted (if you omit thename
attribute, no data from the drop-down list will be submitted).
Each <option>
element inside the <select>
should have a value
attribute containing the data value to submit to the server when that option is selected. If no value
attribute is included, the value defaults to the text contained inside the element. You can include a selected
attribute on an <option>
element to make it selected by default when the page first loads.
app.py
from fastapi import FastAPI, Form, Request
from fastapi.responses import HTMLResponse
from fastapi.templating import Jinja2Templates
app = FastAPI()
templates = Jinja2Templates(directory='templates')
@app.post('/submit')
def submit(car: str = Form(...)):
return car
@app.get('/', response_class=HTMLResponse)
def main(request: Request):
return templates.TemplateResponse('index.html', {'request': request})
templates/index.html
<!DOCTYPE html>
<html>
<body>
<form method="POST" action="/submit">
<label for="cars">Choose a car:</label>
<select name="car" id="cars">
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
<br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>