Flask Routing

Routing is one of the core features of web frameworks; it determines which URL is handled by which function.

Flask routing is a mechanism in web applications that maps URLs to Python functions.

Flask routing is a core part of the Flask application, used to handle requests for different URLs and delegate request handling to corresponding view functions.

The following is a detailed description of Flask routing, including route definitions, parameters, methods, and rules.


Basic Routing

Usage@app.route()The decorator binds the URL path to the view function:

Example

from flask import Flask

app = Flask(__name__)

# Bind the root path "/"
@app.route("/")
def index():
    return "This is the homepage"

# Bind the "/hello" path
@app.route("/hello")
def hello():
    return "Hello, EXAMPLE!"

# Different paths correspond to different functions
@app.route("/about")
def about():
    return "About this site"

Visithttp://127.0.0.1:5000/hellowhen Flask callshello()function.

Visithttp://127.0.0.1:5000/aboutwhen Flask callsabout()function.


Variable Rules

In real applications, URLs often contain dynamic parts, such as user IDs, article titles, etc.

Flask uses<variable_name>The syntax defines dynamic parts in the URL, and the corresponding parameters are automatically passed to the view function.

String variable (default type)

When no type is specified, the variable defaults to a string and matches anything except a slash./Any character other than:

Example

# <username> is a dynamic variable; Flask passes its value to the view function as a keyword parameter
@app.route("/user/<username>")
def show_user(username):
    # Note: username may contain malicious scripts; in production, escaping is required
    return f"<h1>User: {username}</h1>"

# Test visits:
# /user/example → page displays "User: example"
# /user/EXAMPLE → page displays "User: EXAMPLE"

Type Converters

Flask provides multiple built-in converters, through<type:variable_name>Syntax specification:

Converter Description Example URL Match Result
string By default, accepts text that does not contain / /user/example username = "example"
int Positive integer /post/42 post_id = 42
float Positive float /price/19.99 price = 19.99
path Accepts strings containing / /file/a/b/c.txt filepath = "a/b/c.txt"
uuid UUID format string /item/550e8400-e29b-41d4-a716-446655440000 item_id = UUID string

Example

# int converter: Only digits can match; /post/abc returns 404
@app.route("/post/<int:post_id>")
def show_post(post_id):
    # post_id is of type int, not string
    return f"<h1>Article #{post_id}</h1>"

# path converter: Can match paths containing /
@app.route("/file/<path:filepath>")
def show_file(filepath):
    return f"<p>File path: {filepath}</p>"

# float converter: Matches floating-point numbers
@app.route("/price/<float:amount>")
def show_price(amount):
    return f"<p>Price: ¥{amount}</p>"

# uuid converter: Only accepts standard UUID format
@app.route("/item/<uuid:item_id>")
def show_item(item_id):
    return f"<p>Product ID: {item_id}</p>"

Converters not only perform type validation, but also automatically convert matched values into corresponding Python types. For example<int:post_id>What is passed to the view function isintinstead ofstr。


Trailing slash redirect behavior

at the end of the URL/It has a direct impact on route matching behavior, and many beginners are confused by this.

Example

# Rule 1: Ends with / — similar to a directory
# Accessing /projects automatically 308 redirects to /projects/
@app.route("/projects/")
def projects():
    return "Projects list page"

# Rule 2: Does not end with / — similar to a file
# Accessing /about/ returns 404 Not Found
@app.route("/about")
def about():
    return "About page"
Route Definition Visit /projects Visit /projects/
@app.route("/projects/") 308 redirect to /projects/ Normal response
@app.route("/about") Normal response 404 Not Found

This design helps with SEO: it ensures that the same content has only one canonical URL, preventing search engines from indexing the same page twice.


URL Building — url_for

url_for()is Flask's built-in URL generation function, which generates the corresponding URL based on the view function name.

This has many advantages over hard-coded URL strings:

  • If the URL route is modified later, all throughurl_forautomatically updates where generated
  • Automatically handles escaping of special characters
  • The generated path is always an absolute path

Example

from flask import Flask, url_for

app = Flask(__name__)

@app.route("/")
def index():
    return "Home"

@app.route("/login")
def login():
    return "Login page"

@app.route("/user/<username>")
def profile(username):
    return f"{username}'s profile"

# Use test_request_context() to simulate a request context
# This allows url_for() to generate URLs correctly
with app.test_request_context():
    print(url_for("index"))                    # Output /
    print(url_for("login"))                    # Output /login
    print(url_for("login", next="/"))          # Output /login?next=%2F
    print(url_for("profile", username="example"))  # Output /user/example

url_for()The first parameter is the view function name (note: it is the function name, not the URL path).

If the URL contains dynamic variables, pass the corresponding values as keyword arguments.

Extra unknown parameters are automatically concatenated into the query string.


HTTP Methods

By default, the route only responds toGETrequest.

ThroughmethodsThe parameter can specify allowed HTTP methods:

Example

from flask import Flask, request

app = Flask(__name__)

# The same URL responds to both GET and POST requests
@app.route("/login", methods=["GET", "POST"])
def login():
    # Determine the current request type using request.method
    if request.method == "POST":
        # Handle login form submission (executed on POST request)
        username = request.form.get("username")
        return f"<h1>Welcome back, {username}!</h1>"
    else:
        # Display login form (executed on GET request)
        return """
        <form method="post">
<input type="text" name="username" placeholder="Username">
<input type="submit" value="Login">
        </form>
        """

shortcut method decorator

Flask provides shorthand decorators for common HTTP methods to make the code clearer:

Example

# Equivalent to @app.route("/login", methods=["GET"])
@app.get("/login")
def login_form():
    return "<form>...</form>"

# Equivalent to @app.route("/login", methods=["POST"])
@app.post("/login")
def login_submit():
    return "Login successful"

# Also supports @app.put(), @app.delete(), @app.patch()
@app.delete("/post/<int:post_id>")
def delete_post(post_id):
    # API to delete an article
    return f"Article {post_id} deleted"
Convenience Decorators Equivalent syntax Typical use
@app.get("/path") @app.route("/path", methods=["GET"]) Retrieve data, display page
@app.post("/path") @app.route("/path", methods=["POST"]) Create data, submit form
@app.put("/path") @app.route("/path", methods=["PUT"]) Update data (full replacement)
@app.delete("/path") @app.route("/path", methods=["DELETE"]) Delete data
@app.patch("/path") @app.route("/path", methods=["PATCH"]) Update data (partial update)

Automatically handlesIf the route definesGETmethod, Flask automatically adds support forHEADSupport for methods. AlsoOPTIONSMethods are usually handled automatically.


Bind multiple routes at the same time

The same view function can be bound to multiple routes:

Example

# Two different URLs point to the same view function
@app.route("/hello")
@app.route("/hello/<name>")
def greet(name=None):
    # name has a default value of None; when visiting /hello, name is None
    if name is None:
        return "<h1>Hello, World!</h1>"
    return f"<h1>Hello, {name}!</h1>"

Visit/hellowhennameuses the default valueNone, visiting/hello/examplewhennameis"example"。

other extensions