bigywater.tech
Flask · 21

url_for() 如何反向生成 URL

为什么要用 url_for 而不是手写 URL?它能生成什么、不能生成什么?出错时的提示是什么?这篇把常见用法和各种错误都跑一遍。

3
特殊参数个数(本篇演示:_anchor、_external、_scheme)
BuildError
写错 endpoint 或缺参数时的异常类型,会附带建议
SERVER_NAME
没有请求时用 url_for 必须配置的项

参数与特殊参数

实测 · 本机执行输出
  url_for('index')                                         → /
  url_for('user', uid=7)                                   → /user/7
  url_for('user', uid=7, tab='info', page=2)               → /user/7?tab=info&page=2
  url_for('user', uid=7, _anchor='top')                    → /user/7#top
  url_for('user', uid=7, _external=True)                   → http://localhost/user/7
  url_for('user', uid=7, _external=True, _scheme='https')  → https://localhost/user/7
  url_for('files', p='a b/中文.txt')                         → /files/a%20b/%E4%B8%AD%E6%96%87.txt
  url_for('user', uid=7, tags=['a', 'b'])                  → /user/7?tags=a&tags=b
  url_for('user', uid=7, none=None)                        → /user/7

上一篇:路由中的尾部斜杠行为;下一篇:静态文件路由的注册方式。

蓝图的 endpoint

实测 · 本机执行输出
  url_for('shop.item', iid=3) → /shop/item/3 | url_for('shop.shop_home') → /shop/
  在非蓝图请求里写 url_for('.item') → BuildError: Could not build url for endpoint 'item' with values ['iid']. Did you mean 'shop.item' instead?
  请求在蓝图里时 request.blueprint = shop | url_for('.item', iid=3) → /shop/item/3

BuildError

实测 · 本机执行输出
  endpoint 写错 url_for("usr", uid=1): BuildError: Could not build url for endpoint 'usr' with values ['uid']. Did you mean 'user' instead?
  缺少必需参数 url_for("user"): BuildError: Could not build url for endpoint 'user'. Did you forget to specify values ['uid']?
  参数类型不对 url_for("user", uid="x"): ValueError: invalid literal for int() with base 10: 'x'

没有请求上下文

实测 · 本机执行输出
  只有应用上下文,没设 SERVER_NAME → RuntimeError: Unable to build URLs outside an active request without 'SERVER_NAME' configured. Also configure 'APPLICATION_ROOT' and 'PREFERRED_URL_SCHEME' as needed.
  设了 SERVER_NAME=example.test:5000、PREFERRED_URL_SCHEME=https → https://example.test:5000/user/1 | /user/1

app.url_for 与前缀

实测 · 本机执行输出
  app.url_for("user", uid=2) → /user/2
  SCRIPT_NAME=/myapp 时 url_for("hi") → /myapp/hi
  APPLICATION_ROOT=/prefix 且请求 /hi 时 url_for("hi") → /prefix/hi

static 端点

实测 · 本机执行输出
  url_for("static", filename="css/site.css") → /static/css/site.css | url_for("static", filename="a b.js", v=3) → /static/a%20b.js?v=3

分步演示

url_for
本步的对象

    本文用到的工具与边界

    • 本机 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,数字每次运行会有小幅抖动
    • 没有验证:subdomain 与 host_matching 下的 url_for、_method 参数选择不同方法的规则、url_for 在异步任务或 Celery worker 中的使用、_scheme 在反向代理后的实际结果(见第 135 篇)
    京ICP备2026067502号-1京公网安备11010502063487号