Skip to content

Flask - URL Building

Hardcoding URLs within your application (e.g., in templates or redirect functions) is generally a bad practice. If you restructure your routes later (e.g., changing /user/<name> to /profile/<name>), you’ll have to find and update every hardcoded URL manually. This is tedious and error-prone.

Flask provides the url_for() function to dynamically build URLs based on the endpoint name of your view functions. This makes your application more maintainable and less brittle.

url_for() takes the endpoint name of the view function as its first argument. By default, the endpoint name is simply the name of the view function itself (e.g., the endpoint for def admin_dashboard(): is 'admin_dashboard').

If the route associated with the endpoint has variable parts (like <guest_name> in /guest/<guest_name>), you must provide values for these parts as keyword arguments to url_for().

Example:

from flask import Flask, redirect, url_for
app = Flask(__name__)
@app.route('/admin')
def admin_dashboard():
# View function for the admin dashboard
return 'Admin Dashboard'
@app.route('/guest/<guest_name>')
def guest_greeting(guest_name):
# View function for greeting guests
# Using an f-string for modern string formatting
return f'Hello {guest_name}, welcome as Guest!'
@app.route('/user/<name>')
def user_profile(name):
# This function checks the name and redirects using url_for()
if name == 'admin':
# Build URL for the 'admin_dashboard' endpoint
target_url = url_for('admin_dashboard')
# target_url will be '/admin'
return redirect(target_url)
else:
# Build URL for the 'guest_greeting' endpoint,
# providing the required 'guest_name' variable.
target_url = url_for('guest_greeting', guest_name=name)
# If name='Alice', target_url will be '/guest/Alice'
return redirect(target_url)
if __name__ == '__main__':
app.run(debug=True)

How it works:

  • The user_profile(name) function receives a name from the URL (e.g., accessing /user/admin sets name to 'admin').
  • If name is ‘admin’, url_for('admin_dashboard') looks up the route associated with the admin_dashboard function and generates the corresponding URL path, which is /admin.
  • If name is anything else (e.g., ‘Alice’), url_for('guest_greeting', guest_name=name) looks up the route for the guest_greeting function (/guest/<guest_name>) and substitutes the value of name (‘Alice’) for the guest_name variable part, generating the URL path /guest/Alice.
  • The redirect() function then sends a response to the browser, instructing it to navigate to the generated URL.

Testing the Example:

  1. Save the code as app.py and run it (python app.py).

  2. Open your browser and go to http://127.0.0.1:5000/user/admin.

The browser will be redirected to http://127.0.0.1:5000/admin and display:

Admin Dashboard
  1. Now go to http://127.0.0.1:5000/user/Alice (or any name other than ‘admin’).

The browser will be redirected to http://127.0.0.1:5000/guest/Alice and display:

Hello Alice, welcome as Guest!

Benefits of url_for():

  • Maintainability: If you change a route path in the @app.route decorator, url_for() automatically generates the correct new URL everywhere it’s used with that endpoint name. No manual find-and-replace needed.
  • Readability: url_for('profile') is often clearer than /user/profile/view.
  • Handles Escaping: url_for() correctly handles escaping of special characters in variable parts.
  • Absolute URLs: Can generate absolute URLs (including domain name) if needed, using _external=True (e.g., url_for('guest_greeting', guest_name='Bob', _external=True)).

It’s standard practice to use url_for() whenever you need to link to another page within your Flask application, especially in templates and redirects.