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
- Install Python and VSCode or any other IDE.
- Install Flask module.
- Basic understanding of HTML language.
- Basic familiarity with Flask.
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:
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:
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 –
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 –
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 –
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 –
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:
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.