174

我有一个复杂的基于 Flask 的网络应用程序。有许多带有视图功能的单独文件。它们的 URL 是用@app.route('/...')装饰器定义的。有没有办法获取在我的应用程序中声明的所有路线的列表?也许我可以在app对象上调用一些方法?

4

10 回答 10

182

应用程序的所有路由都存储app.url_mapwerkzeug.routing.Map. Rule您可以使用以下方法迭代实例iter_rules

from flask import Flask, url_for

app = Flask(__name__)

def has_no_empty_params(rule):
    defaults = rule.defaults if rule.defaults is not None else ()
    arguments = rule.arguments if rule.arguments is not None else ()
    return len(defaults) >= len(arguments)


@app.route("/site-map")
def site_map():
    links = []
    for rule in app.url_map.iter_rules():
        # Filter out rules we can't navigate to in a browser
        # and rules that require parameters
        if "GET" in rule.methods and has_no_empty_params(rule):
            url = url_for(rule.endpoint, **(rule.defaults or {}))
            links.append((url, rule.endpoint))
    # links is now a list of url, endpoint tuples

有关更多信息,请参阅显示指向创建的新网页的链接。

于 2012-11-10T01:41:30.510 回答
129

我刚遇到同样的问题。上面的那些解决方案太复杂了。只需在您的项目下打开一个新的 shell:

    python
    >>> from app import app
    >>> app.url_map

第一个 ' app ' 是我的项目脚本:app.py,另一个是我的网站名称。

(此解决方案适用于带有少量路线的小型网络)

于 2016-08-09T07:11:28.380 回答
59

我在我的manage.py

@manager.command
def list_routes():
    import urllib
    output = []
    for rule in app.url_map.iter_rules():

        options = {}
        for arg in rule.arguments:
            options[arg] = "[{0}]".format(arg)

        methods = ','.join(rule.methods)
        url = url_for(rule.endpoint, **options)
        line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, url))
        output.append(line)

    for line in sorted(output):
        print line

它通过构建一组虚拟选项来解决缺失的参数。输出如下所示:

CampaignView:edit              HEAD,OPTIONS,GET     /account/[account_id]/campaigns/[campaign_id]/edit
CampaignView:get               HEAD,OPTIONS,GET     /account/[account_id]/campaign/[campaign_id]
CampaignView:new               HEAD,OPTIONS,GET     /account/[account_id]/new

然后运行它:

python manage.py list_routes

有关 manage.py 结帐的更多信息:http: //flask-script.readthedocs.org/en/latest/

于 2013-10-01T12:55:16.760 回答
52

显然,从 0.11 版开始,Flask 有一个内置的 CLI。内置命令之一列出了路线:

FLASK_APP='my_project.app' flask routes
于 2018-12-15T20:34:54.067 回答
43

与乔纳森的回答类似,我选择这样做。我看不到使用 url_for 的意义,因为如果您的参数不是字符串,例如浮点数,它将中断

@manager.command
def list_routes():
    import urllib

    output = []
    for rule in app.url_map.iter_rules():
        methods = ','.join(rule.methods)
        line = urllib.unquote("{:50s} {:20s} {}".format(rule.endpoint, methods, rule))
        output.append(line)

    for line in sorted(output):
        print(line)
于 2014-03-26T04:05:58.243 回答
7

由于您没有指定它必须在命令行中运行,因此可以轻松地在 json 中为仪表板或其他非命令行界面返回以下内容。无论如何,从设计的角度来看,结果和输出真的不应该混为一谈。这是糟糕的程序设计,即使它是一个小程序。然后可以在 Web 应用程序、命令行或其他任何摄取 json 的东西中使用下面的结果。

您也没有指定您需要知道与每条路线关联的 python 函数,因此这更准确地回答了您的原始问题。

我在下面使用自己将输出添加到监控仪表板。如果您想要可用的路由方法(GET、POST、PUT 等),则需要将其与上述其他答案结合使用。

Rule 的repr () 负责转换路由中所需的参数。

def list_routes():
    routes = []

    for rule in app.url_map.iter_rules():
        routes.append('%s' % rule)

    return routes

使用列表推导同样的事情:

def list_routes():
    return ['%s' % rule for rule in app.url_map.iter_rules()]

样本输出:

{
  "routes": [
    "/endpoint1", 
    "/nested/service/endpoint2", 
    "/favicon.ico", 
    "/static/<path:filename>"
  ]
}
于 2018-04-25T15:32:09.123 回答
5

如果您需要自己访问视图函数,请app.url_map使用. 而不是app.view_functions.

示例脚本:

from flask import Flask

app = Flask(__name__)

@app.route('/foo/bar')
def route1():
    pass

@app.route('/qux/baz')
def route2():
    pass

for name, func in app.view_functions.items():
    print(name)
    print(func)
    print()

运行上述脚本的输出:

static
<bound method _PackageBoundObject.send_static_file of <Flask '__main__'>>

route1
<function route1 at 0x128f1b9d8>

route2
<function route2 at 0x128f1ba60>

(请注意包含由 Flask 自动创建的“静态”路由。)

于 2018-12-01T15:56:36.443 回答
4

您可以在导出或设置 FLASK_APP 环境变量后运行以下命令,通过烧瓶外壳查看所有路由。 flask shell app.url_map

于 2019-07-19T08:25:37.713 回答
4

在烧瓶项目所在的目录中使用 cli 命令。

flask routes
于 2021-05-09T13:51:22.067 回答
3

在您的烧瓶应用程序中执行以下操作:

flask shell
>>> app.url_map
Map([<Rule '/' (OPTIONS, HEAD, GET) -> helloworld>,
 <Rule '/static/<filename>' (OPTIONS, HEAD, GET) -> static>])
于 2019-10-30T13:29:51.597 回答