Saturday, November 16, 2024
Google search engine
HomeLanguagesFlask URL Helper Function – Flask url_for()

Flask URL Helper Function – Flask url_for()

In this article, we are going to learn about the flask url_for() function of the flask URL helper in Python.

Flask is a straightforward, speedy, scalable library, used for building, compact web applications. It is a micro framework, that presents developers, useful tools, and, features, for coding REST APIs, and backend data processing, of web apps.

Flask url_for() method

The url_for() method, is used to prepare a URL, for a function dynamically, such that, changing URLs, in the application, is avoided. It accepts, the name of the view function, as the first argument, and, any number of keywords, to be sent(to the view function), as the second argument. 

Syntax: url_for(‘<function_name>’,<key> = <value>)

Web Application Architecture

A web application mainly consists of the presentation(HTML, CSS other static files), and, business logic( here Python files). These should be separated, from each other, for easy maintenance, of the app. Any web app consists of numerous URLs, based on which, the business logic, is passed to the presentation logic. The url_for() function, in Flask, is used to build a URL dynamically. The benefits of the same are as follows –

  • At times we need to restructure, the URLs of our application, based on user data. The url_for() function, makes it easy. Hence we need not hardcode the values here.
  • The paths generated by url_for(), are always absolute.
  • It efficiently handles the escaping of special characters.
  • Url_for() allows us, to modify the routes, and, assure the smooth working of the app links.

In this article, we will learn more about this helper function.

Prerequisites

Using the url_for() method at the Backend/Business Logic side

Consider, a web application, that gives information on Sports. Let’s see the step-by-step implementation:

Step 1: In the Python Flask code, we first import the Flask class, and, render_template from the flask library.

Step 2: The Flask class, is used to create the instance, of the Flask application, as ‘app’. The __name__ magic variable is used to pass the path of the module, to help flask find the templates, and, other static files.

Step 3: Then, we have written a view function, called ‘welcome’. The view function, in Python, returns an HTTP response. The function is decorated with ‘app.route(‘/’)’. This decorator, matches the incoming request URLs,  to the view functions.

Step 4: Thus, incoming requests like ‘localhost:5000/’ will be mapped, to view function – welcome().

Step 5: The welcome() view function, uses the render_template, from the Flask library, to return the HTML template file, called ‘sportsmain.html’. This file is present in the ‘templates’ folder, of our app, local directory.

Step 6: We have created a simple web page as given below.

Step 7: Lastly, we start the Flask web app with debug mode On. This enables us, to locate any errors present, in our application.

Python3




# import the Flask library
from flask import Flask, render_template
  
  
# Create the Flask instance and pass the Flask
# constructor, the path of the correct module
app = Flask(__name__)
  
  
# Default route added using a decorator, for view function 'welcome'
# Landing page of our web application - sportsmain.html
@app.route('/')
def welcome():
    return render_template('sportsmain.html')
  
  
# Start with flask web app, with debug as True,
# only if this is the starting page
if(__name__ == "__main__"):
    app.run(debug=True)


Our landing page sportsmain.html looks as follows:

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sports</title>
</head>
<body>
<h1> Encouragement for sports!</h1>
<h2>Why are sports important?</h2>
<ul>Let us understand -
    <li>Helps in  Mental & Physical toughness</li>
    <li>Helps in developing Self Confidence & Team Spirit</li>
    <li>Teaches you how to organize your time!</li>
</ul>
  
</body>
</html>


Note: Add a separate folder, called ‘templates’, in your project directory. Please ensure, the above ‘sportsmain.html’ file, is present in the templates folder, along with other HTML files. For this example, the following files should be present –

  • sportsmain.html
  • cricket.html
  • baseball.html
  • carrom.html

 Output: The message displayed at the terminal, on starting the application, is as follows:

Message displayed at the terminal on starting the Flask web app

When we open the URL localhost:5000/, in the browser, the view function welcome() renders the ‘sportsmain.html’ file. The output is as shown below:

The localhost:5000 request renders the sportsmain.html page

Suppose, we add another link in the app, like ‘localhost:5000/sport/<name>/<team>’. Here the <name> variable can be ‘cricket’, ‘baseball’, and ‘carrom’. The <team> variable will represent the favorite team. Let us add, corresponding HTML files, for these games, in our ‘templates’ folder. 

Code for other HTML web pages:

cricket.html :

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cricket</title>
</head>
<body>
<p>
  Cricket is played by two teams of 11, with one
  side taking a turn to bat a ball and score runs,
  <br>
  while the other team will bowl and field the
  ball to restrict the opposition from scoring. 
  <br>
  The main objective in cricket is to score as many 
  runs as possible against the opponent.
</p>
<h2>
    Brilliant Cricket Facts
</h2>
<ul>
    <li>The first cricket ball was made
      of wool. ...</li>
    <li>Cricket bats are made from white
      willow. ...</li>
    <li>The longest cricket match was
      14 days long. ...</li>
    <li>A century is when a batsman scores 100
      runs without being bowled out. ...</li>
    <li>England's youngest cricketer was 
      just 17 years old.</li>
</ul>
<br>
<h3>Ooo your favourite team is {{fav}} !!</h3>
</body>
</html>


carrom.html :

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Carrom</title>
</head>
  
<body>
<p>Carrom is a tabletop game which resembles snooker
  or billiards, and the more modern games of subbuteo
  and air hockey.
  <br>
  The game of Carrom is played by
  propelling discs and potting them into the four 
  corner pockets on a wooden playing board. Some 
  variations use small cues but most 
  Carrom is played by hand</p>
<h2>Facts about Carrom</h2>
<ul>
    <li>Invented in India</li>
    <li>In Patiala, India, there is a carrom board
      that has a surface made of glass.</li>
    <li>Maria Irudayam is a Chennai-based carrom
      player who has won the World Championship twice
      and the National Championship of India nine times.</li>
    <li>As of now, the carrom game is not a part 
      of the Olympics or the Commonwealth Games.</li>
</ul>
<h3>Ooo your favourite team is {{fav}} !!</h3>
</body>
</html>


baseball.html :

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Baseball</title>
</head>
<body>
<p>The goal of the game is to score more points
  (runs) than the other team. <br>The players
  on the team at bat attempt to score runs by
  touching all four bases, 
  in order, set at the corners of the 
  square-shaped baseball diamond.</p>
<h2>
    Brilliant Baseball Facts
</h2>
<ul>
    <li>The First MLB Team Was the Cincinnati 
      Red Stockings. ...</li>
    <li>Jackie Robinson Was the First Black
      Major League Player. ...</li>
    <li>Two Players Played in the MLB for 
      27 Seasons. ...</li>
    <li>Edwin Jackson Played For the Most 
      MLB Teams. ...</li>
    <li>John William Lindsey Spent the Most
      Time in the Minors.</li>
  
</ul>
<h3>Ooo your favourite team is {{fav}} !!</h3>
</body>
</html>


Now, any URL link containing “localhost:5000/sport/<name>/<team>”  will be mapped, to the view function, whose decorator has app.route(‘/sport/<name>/<team>’). We will implement the logic, to decide which Sport HTML page (cricket/baseball/carrom), to call, based on the ‘name’ value, in the URL. 

Python code to render all above web pages:

Python3




# import the Flask library
from flask import Flask, redirect, url_for, render_template, request
  
  
# Create the Flask instance and pass the Flask
# constructor the path of the currect module
app = Flask(__name__)
  
  
# Default route added using a decorator for view 
# function 'welcome' Landing page of our web application
@app.route('/')
def welcome():
    return render_template('sportsmain.html')
  
  # View function for URL 'localhost:5000/sport/cricket/india'
  
  
@app.route('/cricket/<favteam>')
def cricket(favteam):
    return render_template('cricket.html', fav=favteam)
  
  # View function for URL 'localhost:5000/sport/baseball/india'
  
  
@app.route('/baseball/<favteam>')
def baseball(favteam):
    return render_template('baseball.html', fav=favteam)
  
  # View function for URL 'localhost:5000/sport/carrom/india'
  
  
@app.route('/carrom/<favteam>')
def carrom(favteam):
    return render_template('carrom.html', fav=favteam)
  
  
# Logic to decide which template file to call based on 'name' variable
# The 'team' variable will be passed to the appropriate view function
# url_for method here calls the appropriate view function and
# passes the parameter required
@app.route('/sport/<name>/<team>')
def game(name, team):
    # If sport is cricket call the view function for 
    # same and pass team name
    if name == 'cricket':
        return redirect(url_for('cricket', favteam=team))
    elif name == 'baseball':
      # If sport is baseball call the view function for
      # same and pass team name
        return redirect(url_for('baseball', favteam=team))
      # If sport is carrom call the view function for 
      # same and pass team name
    elif name == 'carrom':
        return redirect(url_for('carrom', favteam=team))
      # If any other sport is mentioned return the
      # 'workinprogress' webpage
    else:
      # IF the game page is not present return
      # 'workinprogress.html' page
        return render_template('workinprogress.html',
                               sportname=name)
  
  
# Start with flask web app with debug as True only 
# if this is the starting page
if(__name__ == "__main__"):
    app.run(debug=True)


Explanation of the above code:

Consider the following points

  • The view function ‘game()’ is mapped for the following  URLs –
    • ”localhost:5000/sport/cricket/india” 
    • ”localhost:5000/sport/carrom/india”
    • ”localhost:5000/sport/baseball/india”
    •  ”localhost:5000/sport/hockey/india”
  • Based on the above URLs, the if-elif condition, will make a call, to the view functions ‘cricket()’ or ‘baseball()’ or ‘carrom()’.
  • The url_for() helper function, makes it possible, to allow dynamic modification, of links, based on the URL data. 
  • Also, the ‘team’ variable, is passed as a parameter, to the respective game view function, in the url_for() method. 
  • The cricket(), baseball() and carrom() view functions, then call, the corresponding templates, bypassing the value of the favorite team. The templates are the HTML files, present in the ‘templates’ folder.
  • Please note, we have made use, of the Flask Jinja2 template, to pass values of favorite teams, and, sport names from the view function to HTML files.
  • In cases, where some other sport name is mentioned, we are returning an error webpage.
  • Thus, here we have made use of the url_for() method to handle the URL-building logic at the backend.

Output for different URLs 

1) URL – ‘localhost:5000/sport/cricket/India’

Execute the application by passing the URL – ‘localhost:5000/sport/cricket/India’. The url_for() method, will invoke, the view function cricket(). The browser output is as follows –

The browser output on passing cricket as a game

2) URL – ‘localhost:5000/sport/baseball/Japan’

Execute the application by passing the URL – ‘localhost:5000/sport/baseball/Japan’. The url_for() method, will invoke, the view function baseball(). The browser output is as follows –

The browser output on passing Baseball as a game

3) URL – ‘localhost:5000/sport/carrom/India’

Execute the application by passing the URL – ‘localhost:5000/sport/carrom/India’. The url_for() method, will invoke, the view function carrom(). The browser output is as follows –

The browser output on passing Carrom as a game

4) URL – ‘localhost:5000/sport/hockey/India’

If we invoke URL ‘localhost:5000/sport/hockey/India’, it will display the ‘workinprogress.html’ webpage. The browser output is as follows –

The browser output on passing Hockey as a game

Using the url_for() method at the Front End/Presentation Side

In the above example, we made use of url_for(), at the backend, to decide the view function, to call. Similarly, we can use the method in the front end, on the HTML page. Consider the sportsmain.html file code.

Sportsmain.html file with url_for() method:

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sports</title>
</head>
<body>
<h1> Encouragement for sports!</h1>
<h2>Why are sports important?</h2>
<ul>Let us understand -
    <li>Helps in  Mental & Physical toughness</li>
    <li>Helps in developing Self Confidence
      & Team Spirit</li>
    <li>Teaches you how to organize your time!</li>
</ul>
  
<br>
<h3> There are indoor sports and outdoor sports </h3>
  Click on the links below to know more about them
   <nav>
        <a href="{{ url_for('indoor') }}">Indoor Games</a>
        <a href="{{ url_for('outdoor') }}">Outdoor Games</a>
    </nav>
</body>
</html>


Here, we have added logic, on the HTML page, to invoke the mapped view function (indoor or outdoor), in the Python code. 

Note: Add a separate folder, called ‘templates’, in your project directory. Please ensure, the above ‘sportsmain.html’ file, is present in the templates folder, along with other HTML files. For this example, the following files should be present –

  • sportsmain.html
  • indoor.html
  • outdoor.html

indoor.html:

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sports</title>
</head>
<body>
<h1> Indoor Games</h1>
<ul>
    <li>Chess</li>
    <li>Table tennis</li>
    <li>carrom</li>
</ul>
  
</body>
</html>


outdoor.html:

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Sports</title>
</head>
<body>
<h1> Outdoor Games</h1>
<ul>
    <li>Cricket</li>
    <li>Football</li>
    <li>Baseball</li>
    <li>Vollyball</li>
</ul>
  
</body>
</html>


Python Code with Indoor and Outdoor view functions:

The Python code and logic, are the same as the one, used in the previous example, with the only addition, of indoor() and outdoor() view functions, to map to the frontend hyperlinks( <a> tags).

Python3




#import the Flask library
from flask import Flask,redirect,url_for,render_template,request
  
  
#Create the Flask instance and pass the Flask constructor the path of the currect module
app = Flask(__name__)
  
  
#Default route added using a decorator for view function 'welcome'
#Landing page of our web application
@app.route('/')
def welcome():
    return render_template('sportsmain.html')
  
@app.route('/cricket/<favteam>')
def cricket(favteam):
    return render_template('cricket.html',fav = favteam)
  
@app.route('/baseball/<favteam>')
def baseball(favteam):
    return render_template('baseball.html',fav = favteam)
  
@app.route('/carrom/<favteam>')
def carrom(favteam):
    return render_template('carrom.html',fav = favteam)
  
  #view function for indoor games option present on HTML page
@app.route('/indoor')
def indoor():
    return render_template('indoor.html')
  
  #view function for outdoor games option present on HTML page
@app.route('/outdoor')
def outdoor():
    return render_template('outdoor.html')
  
@app.route('/sport/<name>/<team>')
def game(name,team):
    if name == 'cricket':
        return redirect(url_for('cricket',favteam = team))
    elif name == 'baseball':
        return redirect(url_for('baseball',favteam = team))
    elif name == 'carrom':
        return redirect(url_for('carrom',favteam = team))
    else:
        return render_template('workinprogress.html',sportname=name)
  
#Start with flask web app with debug as True only if this is the starting page
if(__name__=="__main__"):
    app.run(debug=True)


After adding in the templates folder, files outdoor.html, and indoor.html, the ‘sporstmain.html’ webpage looks as:

After including Outdoor and Indoor links in the Main webpage

Explanation: In the above code when we click on any of the links (Indoor Games or Outdoor Games). We will be directed to the respective page.

Thus, we learned that the url_for() helper function, is extremely beneficial, wherein dynamic URL building is required.

RELATED ARTICLES

Most Popular

Recent Comments