bigywater.tech
Flask · 16

@app.route() 如何注册路由

一行 @app.route(...) 之后,Flask 内部多了什么?它和 add_url_rule 是什么关系?endpoint 是怎么来的?这篇把这些一一打印出来。

3 行
Scaffold.route 里 decorator 的代码行数(取 endpoint、add_url_rule、return f)
GET、HEAD、OPTIONS
methods 默认值对应的实际方法集合
AssertionError
第一个请求之后再注册路由时的报错类型

route 注册了什么

实测 · 本机执行输出
  源码:
      1 | @app.route("/hello", methods=["GET"])
      2 | def hello(): return "hi"
  注册前 → 后:规则数 1 → 2 | view_functions 数 1 → 2
  装饰器返回的是原函数: hello | callable: True | 类型: function
  Rule 对象:rule = /hello | endpoint = hello | methods = ['GET', 'HEAD', 'OPTIONS'] | strict_slashes = True | view_functions["hello"] is hello: True

下一篇:URL Rule 与路由匹配顺序。

route 与 add_url_rule

实测 · 本机执行输出
  @route 的规则  : [('/x', 'f', ['OPTIONS', 'POST'])]
  add_url_rule : [('/x', 'f', ['OPTIONS', 'POST'])]
  相同: True
  Scaffold.route 里的 decorator(原样):
        def decorator(f: T_route) -> T_route:
            endpoint = options.pop("endpoint", None)
            self.add_url_rule(rule, endpoint, f, **options)
            return f
    
        return decorator

endpoint

实测 · 本机执行输出
  两个同名函数 → AssertionError: View function mapping is overwriting an existing endpoint function: view
  自定义 endpoint 后 view_functions 的键: ['c_custom', 'static', 'view']

多路径与多方法

实测 · 本机执行输出
  /one    → ['GET', 'HEAD', 'OPTIONS']
  /three  → ['OPTIONS', 'POST']
  /two    → ['GET', 'HEAD', 'OPTIONS']
  请求: {'/one': 200, '/two': 200, '/three': 405} | POST /three: 200

注册时机

实测 · 本机执行输出
  AssertionError: The setup method 'get' can no longer be called on the application. It has already handled its first request, any changes will not be applied consistently.

flask routes

实测 · 本机执行输出
Endpoint  Methods    Rule                   
--------  ---------  -----------------------
items     GET, POST  /items                 
static    GET        /static/<path:filename>
user      GET        /users/<int:uid>

分步演示

@route
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:endpoint 名在蓝图里的前缀规则(见第 26 篇)、defaults 与 redirect_to 参数、subdomain 与 host_matching 参数、class-based view(MethodView)注册路由的差别、add_url_rule 的 provide_automatic_options 参数
    京ICP备2026067502号-1京公网安备11010502063487号