Reputation: 25
How do I submit the value
selected from an HTML dropdown menu/list in the frontend, using HTML-Jinja2 template, to a FastAPI backend?
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/Jinja2 template:
<!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.
Upvotes: 1
Views: 1929
Reputation: 34551
You need to make sure that the action
attribute—which specifies where to send the form-data
—is included in the HTML <form>
, when submitting it (examples can also be found at W3schools <form>
tag docs). Also, for 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 from the drop-down list. 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>
Upvotes: -1