确定哪个路由将用于请求 URL

Determining which route would be used for a request URL

在 Flask 框架中,我希望能够确定选择哪个请求路由来为 URL 提供服务,而不必实际请求 URL 本身。例如,如果我有这样的应用程序:

import flask

app = flask.Flask(__name__)

@app.route('/')
def index():
    pass

@app.route('/<id:int>')
@app.route('/<id:int>-<slug>')
def show_page(id, slug = None):
    pass

然后我希望能够做类似的事情(虚构的例子):

route = app.get_url_rule("/12345")

并得到如下结果:

('show_page', {'id':12345,'slug':None})

据我所知,Flask 本身并没有公开任何类似的功能,但是有没有办法深入到它的请求路由层(或者可能是 Werkzeug)来自己实现这个?

您正在寻找的结果正是 Flask 通过 Werkzeug 进行路由的结果。当您装饰视图函数时,规则会在 werkzeug.routing.Map. When the app handles a request, the map is bound to the request to create a MapAdapter. The adapter has a match() 方法的实例中注册,该方法 returns 与 endpoint, args 匹配或引发路由错误,例如 307、404 或 405。 Flask 调用this 并使用结果调用适当的视图函数。

调用app.create_url_adapter()根据应用程序配置获取适配器。当不在请求中时,这需要配置 SERVER_NAME。然后调用 adapter.match(url) 进行匹配。此示例忽略路由异常和 returns None.

from werkzeug.exceptions import HTTPException

# remember to configure app.config["SERVER_NAME"]

def match_url(url):
    adapter = app.get_url_adapter()
    
    try:
        return adapter.match(url)
    except HTTPException:
        return None

呼叫 match_url("/12345-example") returns ('show_page', {'id': 12345, 'slug': 'example'}).

请注意,这通常没有用,因为 Flask 的要点是它已经进行路由并调用适当的视图。

我用你的路线代码试过 Davidism 的方法,以防这有帮助...

from flask import Flask, request

app = Flask(__name__)

@app.route('/<int:id>')
@app.route('/<int:id>-<slug>')
def show_page(id, slug = None):
    adapter = app.create_url_adapter(request)
    endpoint, values = adapter.match()
    
    # Return this to frontend of ease of demo
    return {endpoint: values}

请求 /123 returns:

{
  "show_page": {
    "id": 123
  }
}

请求 /123-abc returns:

{
  "show_page": {
    "id": 123, 
    "slug": "abc"
  }
}