URL-defined routing API
Flask provides three ways to define routing rules:@app.route()Decorator,add_url_rule()Methods, Direct Operationsurl_map。
URL variable converter
| Converter | Syntax | Matching rules | Python types |
|---|---|---|---|
| string | <string:name> or <name> | Any text without / (default) | str |
| int | <int:id> | Positive integer | int |
| float | <float:value> | Positive float | float |
| path | <path:filepath> | Any text (including /) | str |
| any | <any(a,b,c):item> | Match any value in the list | str |
| uuid | <uuid:id> | Standard UUID format | str |
add_url_rule parameters
| Parameter | Type | Description |
|---|---|---|
| rule | str | URL rule string, such as "/user/<username>" |
| endpoint | str | Endpoint name, defaults to the function name. url_for uses this to reference the route. |
| view_func | callable | View function. Can be omitted; stored in the view_functions dictionary later. |
| defaults | dict | Default values for URL variables, such as defaults={"page": 1} |
| subdomain | str | Subdomain matching. Requires enabling subdomain_matching |
| methods | list | Allowed HTTP methods. Default ["GET"] (HEAD and OPTIONS are automatically added) |
| host | str | Hostname matching. Requires enabling host_matching |
Trailing slash behavior
| Rules | Access without / | Access with / |
|---|---|---|
| @app.route("/projects/") | 308 redirect to /projects/ | Normal access |
| @app.route("/about") | Normal access | 404 Not Found |
Default value route
Optional URL variables can be implemented via the defaults parameter:
Example
# Two URLs point to the same function; /users/ is equivalent to /users/page/1
@app.route("/users/", defaults={"page": 1})
@app.route("/users/page/<int:page>")
def show_users(page):
return f"Showing page {page}"
# Access /users/ → page=1
# Access /users/page/3 → page=3
@app.route("/users/", defaults={"page": 1})
@app.route("/users/page/<int:page>")
def show_users(page):
return f"Showing page {page}"
# Access /users/ → page=1
# Access /users/page/3 → page=3
If both the default-value route and the route with variables exist, accessing the URL with default values will be 308-redirected to the simplified form.
Custom Converter
Example
from werkzeug.routing import BaseConverter
# Define a custom type converter
class ListConverter(BaseConverter):
"""Matches a comma-separated list, e.g., /tags/python,flask"""
def to_python(self, value):
return value.split(",")
def to_url(self, values):
return ",".join(values)
# Register to url_map
app.url_map.converters["list"] = ListConverter
# Use a custom converter
@app.route("/tags/<list:tags>")
def show_tags(tags):
# tags is a Python list: ["python", "flask", "web"]
return f"Tags: {', '.join(tags)}"
# Define a custom type converter
class ListConverter(BaseConverter):
"""Matches a comma-separated list, e.g., /tags/python,flask"""
def to_python(self, value):
return value.split(",")
def to_url(self, values):
return ",".join(values)
# Register to url_map
app.url_map.converters["list"] = ListConverter
# Use a custom converter
@app.route("/tags/<list:tags>")
def show_tags(tags):
# tags is a Python list: ["python", "flask", "web"]
return f"Tags: {', '.join(tags)}"