烧瓶:无法解决软件包中的端点位置

时间:2018-12-10 14:49:32

标签: flask werkzeug

注意:从最初的问题开始进行了大量修改,仅提供了最少的示例。原始标题也具有误导性。

我花了几天时间将一堆单独的应用程序和帮助程序模块重构为一个带有蓝图的大程序包。 Flask的实际内容在软件包的顶级目录下几层,而我已经在该目录中进行了所有测试。

包装完程序包并安装完之后,url_for()调用不再起作用,因为应用程序规则中的端点现在包括蓝图视图功能的完整路径,而不仅仅是最后一点。

这是一个说明问题的最小示例(下面附有文件):

当从其自己的目录中运行应用程序时,规则如下所示:

$ python foo/test.py 
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/bar/' (HEAD, OPTIONS, GET) -> bar.index>,
 <Rule '/' (HEAD, OPTIONS, GET) -> index>,
 <Rule '/other' (HEAD, OPTIONS, GET) -> other>]

...这是从模块的基本目录运行时的样子:

$ python test.py
[<Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>,
 <Rule '/bar/' (HEAD, OPTIONS, GET) -> foo.bar.index>,
 <Rule '/' (HEAD, OPTIONS, GET) -> index>,
 <Rule '/other' (HEAD, OPTIONS, GET) -> other>]

请注意,“ /”和“ / other”(在应用程序中定义)的端点保持不变,而“ / bar /”(在蓝图中定义)的端点将获得包名称“ foo”作为前缀。目前,我所有的url_for()调用都使用“短”端点路径,而我希望将其保留为这种方式,部分原因是我不想多次添加完整的程序包名称,而且还因为我不确定目录树将永远保持不变。

这是文件的样子:

$ tree
.
├── foo
│   ├── app.py
│   ├── bar.py
│   ├── __init__.py
│   └── test.py
└── test.py
$ cat ./foo/app.py
import flask
from bar import blp

app = flask.Flask(__name__)
app.register_blueprint(blp, url_prefix='/bar')

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

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

$ cat ./foo/bar.py
import flask

blp = flask.Blueprint(__name__, __name__)

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

$ cat ./foo/__init__.py

$ cat ./foo/test.py
from app import app
import pprint

rules = app.url_map.__dict__['_rules']
pprint.pprint(rules)

$ cat ./test.py
from foo.app import app
import pprint

rules = app.url_map.__dict__['_rules']
pprint.pprint(rules)

1 个答案:

答案 0 :(得分:1)

问题是由您分配给蓝图的名称引起的。蓝图中的每个规则都以名称为前缀。

使用__name__作为蓝图的名称(蓝图构造函数的第一个参数)。在测试用例foo/test.py中,蓝图名称为bar。在测试用例test.py中,蓝图的名称为foo.bar

解决方案是按如下方式重写bar.py文件:

import flask

blp = flask.Blueprint('bar', __name__)

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