5.5. Variables in URLs#
In this section, we’ll explore how Flask allows us to create dynamic web pages by passing variables through URLs. This is useful when we want our web pages to display different content depending on the value passed in the URL.
5.5.1. Basic Example#
Let’s start with a simple example where we’ll use Flask to display a message that includes a variable from the URL.
from flask import Flask
app = Flask(__name__)
@app.route('/greet/<name>')
def greet(name):
return "Hello, {}!".format(name)
app.run(debug=True, port=5000)
Explanation
Defining the route:
The
@app.route('/greet/<name>')
decorator tells Flask that when someone visits a URL that matches/greet/<name>
, the greet() function should be executed.<name>
is a placeholder in the URL that acts as a variable. Whatever value the user types in place of<name>
will be passed to thegreet()
function.
Route function:
The function
greet(name)
acceptsname
as a parameter. Flask automatically extracts the value from the URL and passes it to the function.We return a simple message that includes the
name
variable, which will be displayed on the web page.
5.5.2. Review Page#
Now let’s take a look at how we can use this concept in our “Movie Reviews” website.
We’ll create a page that shows all the information for a movie review based on its
id
. The id
is passed as a variable in the URL.
For example, visiting http://127.0.0.1:5000/movie/2 would display the details of “Barbie.”
1from flask import Flask, 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('/movie/<int:movie_id>')
11def movie_page(movie_id):
12 # Get the movie review by its ID
13 query = text("SELECT * FROM reviews WHERE id={}".format(movie_id))
14 result = connection.execute(query).fetchall()
15
16 if len(result) > 0:
17 # Take first (hopefully the only) result
18 movie = result[0]
19 return render_template('movie_page.html', movie=movie)
20 else:
21 return "Movie not found", 404
22
23app.run(debug=True, port=5000)
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>{{ movie[1] }}</title>
5 </head>
6 <body>
7 <p><a href="/">Home</a></p>
8 <hr>
9
10 <h1>{{ movie[1] }} ({{ movie[2] }})</h1>
11 <p><b>Genre:</b> {{ movie[3] }}</p>
12 <p><b>Review Date:</b> {{ movie[4] }}</p>
13 <p><b>Score:</b> {{ movie[5] }}/10</p>
14 <p><b>Review:</b> {{ movie[6] }}</p>
15 </body>
16</html>
Explanation
Defining the Route:
The
@app.route('/movie/<int:movie_id>')
decorator registers a route wheremovie_id
is an integer variable that will be extracted from the URL.When someone visits
/movie/1
, Flask will extract the value1
and pass it to themovie_page()
function asmovie_id
.
Function Logic:
Inside the
movie_page()
function, we use movie_reviews.get(movie_id) to retrieve the movie data that matches the givenid
. If a movie with thatid
exists, it returns the corresponding data. If not, it returns a 404 error with message"Movie not found"
.
Rendering the Template:
The
render_template('movie_page.html', movie=movie)
line uses Flask’s template engine to render an HTML page and pass the movie data to it.
5.5.3. Complete Example#
Project structure:
├── app.py
├── movies.db
└── templates
└── index.html
└── movie_page.html
1from flask import Flask, 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('/')
10def home():
11 # SQL query to select all movies
12 query = text("SELECT * FROM reviews")
13 result = engine.execute(query).fetchall()
14
15 # Render the template and pass the result
16 return render_template('index.html', movies=result)
17
18@app.route('/movie/<int:movie_id>')
19def movie_page(movie_id):
20 # Get the movie review by its ID
21 query = text("SELECT * FROM reviews WHERE id={}".format(movie_id))
22 result = connection.execute(query).fetchall()
23
24 if len(result) > 0:
25 # Take first (hopefully the only) result
26 movie = result[0]
27 return render_template('movie_page.html', movie=movie)
28 else:
29 return "Movie not found", 404
30
31app.run(debug=True, port=5000)
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <title>Movie Reviews</title>
5 </head>
6 <body>
7 <h1>Movie Reviews</h1>
8 <ul>
9 {% for movie in movies %}
10 <li><a href="/movie/{{ movie[0]}}">{{ movie[1] }} ({{ movie[2] }}) - Score: {{ movie[5] }}</a></li>
11 {% endfor %}
12 </ul>
13 </body>
14</html>
Explanation:
For each movie, we link to the corresponding movie page
1<!DOCTYPE html>
2<html>
3 <head>
4 <title>{{ movie[1] }}</title>
5 </head>
6 <body>
7 <h1>{{ movie[1] }} ({{ movie[2] }})</h1>
8 <p><strong>Genre:</strong> {{ movie[3] }}</p>
9 <p><strong>Review Date:</strong> {{ movie[4] }}</p>
10 <p><strong>Score:</strong> {{ movie[5] }}/10</p>
11 <p><strong>Review:</strong> {{ movie[6] }}</p>
12 </body>
13</html>