5.6. Forms (GET)#
HTML forms are essential for collecting user input, and the GET method is one of the key ways to send that data to a server. In this section, we’ll explore how GET forms work, how Flask handles GET requests, and how we can use query strings to filter data. We’ll also build a movie filtering page as an example.
5.6.1. 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 the GET
method on this page. Forms involving POST
are
described on Forms (POST).
5.6.2. HTML Forms#
A HTML form that uses is a structure that allows users to submit data through the URL
of a web page. 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).
5.6.3. 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.
5.6.4. Example Form#
Here’s an example of a form using GET
where users can search by name:
<!DOCTYPE html>
<html>
<head>
<title>Search Form</title>
</head>
<body>
<h1>Search</h1>
<form action="/search" method="GET">
<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 action="/search" method="GET">
creates a form that submits data to the/search
URL using the GET method. This means the input will appear in the URL after submission.<input type="text" id="term" name="term">
creates a text input for the user’s search term. Thename
attribute will become the key in the query string.<input type="submit" value="Search">
creates a button to submit the form data.
When the form is submitted with “Flask” as the search term, the URL will look like this:
5.6.5. 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
/search
route listens for GET requests.request.args.get('term', '')
is used to retrieve the value of theterm
parameter 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.
5.6.6. 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:
├── 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')
8
9@app.route('/search')
10def filter_movies():
11 return render_template('search.html')
12
13@app.route('/filter', methods=['GET'])
14def filter_movies():
15 # Get filter parameters from the query string
16 genre = request.args.get('genre', '')
17 score = request.args.get('score', '')
18
19 conditions = []
20 if genre:
21 conditions.append("genre={}".format(genre))
22 if score:
23 conditions.append("score>={}".format(score))
24
25 condition_str = " and ".join(conditions)
26
27 # Get the movie review that match the conditions
28 query = text("SELECT * FROM reviews WHERE {}".format(condition_str))
29 result = connection.execute(query).fetchall()
30
31 return render_template('movie_list.html', movies=filtered_movies)
32
33app.run(debug=True, port=5000)
Explanation
<form action="/filter" method="GET">
creates a form that submits the selected filters to the/filter
URL 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
/filter
route listens for GET requests with query string parameters for filtering movies.request.args.get('genre', '')
andrequest.args.get('score', '')
retrieve the values of thegenre
andscore
parameters 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.html
template, 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.
5.6.7. Glossary#
- Query String#
TODO