6.6. Forms - Part 1#
HTML forms are essential for collecting user input on webpages. In this section
we will learn how to create forms with HTML, how to send the form data to a
webserver using a HTTP GET request using query strings and handle the request on a web server.
We’ll use these form submissions to filter movie reviews in our case study as an example.
6.6.1. HTML Forms#
A HTML form consists of
a
formelementa set of
inputelements inside the form element.
Here’s an example of a form
<!DOCTYPE html>
<html>
<head>
<title>Search Form</title>
</head>
<body>
<h1>Search</h1>
<form>
<label for="query">Enter your search:</label>
<input type="text" id="term" name="term"><br><br>
<input type="submit" value="Search">
</form>
</body>
</html>
Explanation
<form>specifies the start of a form and encapsulates all the inputs that are to be submitted with the form.<input type="text" id="term" name="term">creates a text input for the user’s search term. Thenameattribute will become the key in the query string.<input type="submit" value="Search">creates a button to submit the form data.
6.6.2. Form Inputs#
The HTML specification defines a number of valid input types. Common
examples are:
checkboxnumberradiotext
There is also a special type called submit, which creates a button that
submits the form when clicked.
A full list of valid input types can be found here
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input
6.6.3. Forms over HTTP#
When a form is submitted, the browser sends the form data to the server using HTTP. The two most common methods are:
GET: Sends data as part of the URL, typically used for retrieving data.POST: Sends data in the body of the request, used for submitting data such as forms or file uploads.
We will focus on submitting forms using GET requests on this page.
Note
Forms using POST requests are described in
Forms - Part 2.
For forms using GET the data is encoded in the URL itself, making them
ideal for:
Search queries
Filters for content (e.g., filtering movies by genre)
Bookmarkable URLs (since the data is visible in the URL, users can save and share the link)
Everyday examples include search bars on websites (e.g., Google) and filters on e-commerce sites (e.g., filtering by price or category).
6.6.4. Query Strings#
When using the GET, the data is sent in the URL as a query string.
Query strings consist of key-value pairs appended to the URL, and they follow
this format:
http://example.com/search?key1=value1&key2=value2
Key: The name of the input field in the form.
Value: The value entered by the user.
6.6.5. Example Form#
Here’s an example of a form using GET where users can search by name:
1<!DOCTYPE html>
2<html>
3<head>
4 <title>Search Form</title>
5</head>
6<body>
7 <h1>Search</h1>
8 <form action="/search" method="GET">
9 <label for="term">Enter your search:</label>
10 <input type="text" id="term" name="term"><br><br>
11
12 <input type="submit" value="Search">
13 </form>
14</body>
15</html>
Explanation
<form action="/search" method="GET">creates a form that submits data to the/searchURL using the GET method. This means the input will appear in the URL after submission.
When the form is submitted with “Flask” as the search term, the URL will look like this:
6.6.6. Handling Query Strings#
Here’s how you can handle the query string data in Flask:
from flask import Flask, request
app = Flask(__name__)
@app.route('/search', methods=['GET'])
def search():
# Access the query string data
term = request.args.get('term', '')
if term:
return f"You searched for: {term}"
else:
return "No search term provided."
app.run(debug=True, port=5000)
Explanation
The
/searchroute listens for GET requests.request.args.get('term', '')is used to retrieve the value of thetermparameter from the URL. The request.args dictionary contains all the query string data. If no value is provided, it defaults to an empty string ('').The server returns a message that displays what the user searched for.
6.6.7. Example: Filter Reviews#
Let’s create an example where we filter the movies in the “Movie Reviews” database by attributes like genre or review score. The user will select filters using a form, and the results will be displayed based on the selected filters.
Project structure:
movie-reviews
│
├── app.py
├── movies.db
└── templates/
├── search.html
└── filter.html
1from flask import Flask, request, render_template
2from sqlalchemy import create_engine, text
3
4app = Flask(__name__)
5
6# Connect to the database
7engine = create_engine('sqlite:///movies.db')
8connection = engine.connect()
9
10@app.route('/search')
11def search():
12 return render_template('search.html')
13
14@app.route('/filter', methods=['GET'])
15def filter_movies():
16 # Get filter parameters from the query string
17 genre = request.args.get('genre', '')
18 score = request.args.get('score', '')
19
20 conditions = []
21 if genre:
22 conditions.append("genre = '{}'".format(genre))
23 if score:
24 conditions.append("review_score >= {}".format(score))
25
26 condition_str = " AND ".join(conditions)
27
28 # Get the movie review that match the conditions
29 query = text("SELECT * FROM reviews WHERE {}".format(condition_str))
30 result = connection.execute(query).fetchall()
31
32 return render_template('filter.html', movies=result)
33
34app.run(debug=True, port=5000)
Explanation
<form action="/filter" method="GET">creates a form that submits the selected filters to the/filterURL using the GET method.<select id="genre" name="genre">creates a dropdown list of genres. Thename="genre"attribute ensures that the selected genre is sent as a query string parameter.<input type="number" id="score" name="score">allows users to specify a minimum review score. The name=”score” attribute ensures this value is sent as a query string parameter.<input type="submit" value="Filter Movies">sends the selected filter options to the server when clicked.
When the form is submitted with “Action” as the genre and “8” as the minimum score, the URL will look like this:
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>Search Reviews</title>
5 </head>
6 <body>
7 <h1>Filter Movies</h1>
8 <form action="/filter" method="GET">
9 <label for="genre">Genre:</label>
10 <select id="genre" name="genre">
11 <option value="">Any</option>
12 <option value="Action">Action</option>
13 <option value="Comedy">Comedy</option>
14 <option value="Drama">Drama</option>
15 <option value="Animation">Animation</option>
16 </select><br><br>
17
18 <label for="score">Minimum Review Score:</label>
19 <input type="number" id="score" name="score" min="1" max="10"><br><br>
20
21 <input type="submit" value="Filter Movies">
22 </form>
23 </body>
24</html>
Explanation
The
/filterroute listens for GET requests with query string parameters for filtering movies.request.args.get(‘genre’, ‘’) and request.args.get(‘score’, ‘’) retrieve the values of the
genreandscoreparameters from the URL. If no value is provided, they default to an empty string ('').The reviews` table is queried to retrieve reviews that match the conditions.
The filtered list of movies is passed to the
movie_list.htmltemplate, which displays the movies.
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>Movie List</title>
5 </head>
6 <body>
7 <h1>Filtered Movies</h1>
8 <ul>
9 {% for movie in movies %}
10 <li>{{ movie[1] }} ({{ movie[2] }}) - Score: {{ movie[5] }}</li>
11 {% endfor %}
12 </ul>
13 </body>
14</html>
Explanation
This template loops through the filtered movies and displays each movie’s title, genre, and review score in a list.
6.6.8. Glossary#
- Query String#
A query string is the part of a URL that contains additional information or parameters that a web server can use to process a request, often appearing after a “?” in the URL (e.g.,
?search=books).