Колба: устранение неполадок при определении местоположения конечных точек в пакете - PullRequest
0 голосов
/ 10 декабря 2018

ПРИМЕЧАНИЕ: Сильно отредактировано от исходного вопроса, включая минимальный пример.Оригинальное название также вводило в заблуждение.

Я потратил несколько дней на то, чтобы перегруппировать несколько отдельных приложений и вспомогательных модулей в один большой пакет с чертежами.Фактический материал Flask находится на несколько уровней ниже каталога верхнего уровня пакета, и я провел все свои тесты в этом каталоге.

После того, как пакет был упакован и установлен, url_for () вызывает don 'больше не работает, потому что конечные точки в правилах приложения теперь включают полный путь к функциям чертежа, а не только последний бит.

Вот минимальный пример, который иллюстрирует проблему (файлы, добавленные ниже):

Вот как выглядят правила, когда приложение запускается из своего собственного каталога:

$ 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 голосов
/ 13 декабря 2018

Проблема генерируется именем, которое вы назначаете для Blueprint.Каждому правилу в Blueprint предшествует имя.

Поскольку вы используете __name__ в качестве имени для Blueprint (Первый аргумент конструктора Blueprint).В тестовом примере foo/test.py имя проекта - bar.В тестовом примере test.py имя Blueprint - foo.bar.

. Решение состоит в том, чтобы переписать ваш файл bar.py следующим образом:

import flask

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

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