#python #flask #jinja2
#python #flask
Вопрос:
У меня есть приложение Flask с чертежами. Каждый blueprint предоставляет несколько шаблонов. Когда я пытаюсь отобразить index.html
шаблон из второго чертежа, вместо него отображается шаблон первого чертежа. Почему blueprint2 переопределяет шаблоны blueprint1? Как я могу отобразить шаблоны каждого чертежа?
app/
__init__.py
blueprint1/
__init__.py
views.py
templates/
index.html
blueprint2/
__init__.py
views.py
templates/
index.html
blueprint2/__init__.py
:
from flask import Blueprint
bp1 = Blueprint('bp1', __name__, template_folder='templates', url_prefix='/bp1')
from . import views
blueprint2/views.py
:
from flask import render_template
from . import bp1
@bp1.route('/')
def index():
return render_template('index.html')
app/__init__.py
:
from flask import Flask
from blueprint1 import bp1
from blueprint2 import bp2
application = Flask(__name__)
application.register_blueprint(bp1)
application.register_blueprint(bp2)
Если я изменю порядок регистрации чертежей, то шаблоны blueprint2 переопределят шаблоны blueprint1.
application.register_blueprint(bp2)
application.register_blueprint(bp1)
Комментарии:
1. Вы должны опубликовать свои
__init__.py
файлы.2. Спасибо, теперь отправлено.
3. Я думаю, проблема в
Blueprint('bp1', ...
том, что вы должны зарегистрировать полное имя каталога, как вBlueprint('blueprint1',
4. Это не так, я изменил имя, но ничего нового не произошло. Я обнаружил, что порядок, в котором я зарегистрировал проект, определил, какую страницу отображать. Первый, который я зарегистрировал, переопределит второй шаблон.
5. Вы пытались изменить
template_folder='templates'
? может быть, чтобыtemplate_folder='blueprint2/templates'
? или дает ему полный путь?
Ответ №1:
Это работает точно так, как задумано, хотя и не так, как вы ожидаете.
Определение папки шаблона для схемы элементов только добавляет папку в путь поиска шаблона. Это не означает, что вызов render_template
из представления чертежа будет проверять только эту папку.
Шаблоны просматриваются сначала на уровне приложения, затем в порядке регистрации чертежей. Это делается для того, чтобы расширение могло предоставлять шаблоны, которые могут быть переопределены приложением.
Решение заключается в использовании отдельных папок в папке template для шаблонов, связанных с конкретными чертежами. Их все еще можно переопределить, но гораздо сложнее сделать это случайно.
app/
blueprint1/
templates/
blueprint1/
index.html
blueprint2/
templates/
blueprint2/
index.html
Укажите каждый чертеж в его templates
папке.
bp = Blueprint('bp1', __name__, template_folder='templates')
При рендеринге укажите на конкретный шаблон под templates
папкой.
render_template('blueprint1/index.html')
Подробнее об этом читайте в выпуске Flask №1361.
Ответ №2:
Я смутно помню, что у меня были проблемы с чем-то подобным на ранней стадии. Вы не опубликовали весь свой код, но у меня есть четыре предложения, основанные на том, что вы написали. Попробуйте первый, протестируйте его, а затем, если он все еще не работает, попробуйте следующие, но независимо протестируйте их, чтобы увидеть, работают ли они:
Во-первых, я не могу видеть ваш views.py
файл, поэтому убедитесь, что вы импортируете соответствующий шаблон в свои views.py
файлы:
from . import bp1 # in blueprint1/views.py
from . import bp2 # in blueprint2/views.py
Во-вторых, вам может потребоваться исправить относительные операторы импорта __init__.py
следующим образом (обратите внимание на период, предшествующий вложенным папкам):
from .blueprint1 import blueprint1 as bp1
from .blueprint2 import blueprint2 as bp2
В-третьих, поскольку вы жестко задаете путь к своим шаблонам в своей render_template
функции, попробуйте удалить template_folder='templates'
его из определения вашего blueprint.
В-четвертых, похоже, что вы назвали url_prefix для своего blueprint как «/bp1» при его регистрации. Поэтому, если жестко запрограммированная ссылка на вашу файловую систему по-прежнему не работает:
render_template('blueprint1/index.html')
затем также попробуйте это и посмотрите, что произойдет:
render_template('bp1/index.html')
Опять же, я не вижу вашего полного кода, но надеюсь, это поможет.