Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
665 views
in Technique[技术] by (71.8m points)

python - render_template from Flask blueprint uses other blueprint's template

I have a Flask app with blueprints. Each blueprint provides some templates. When I try to render the index.html template from the second blueprint, the first blueprint's template is rendered instead. Why is blueprint2 overriding blueprint1's templates? How can I render each blueprint's templates?

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)

If I change the order the blueprints are registered, then blueprint2's templates override blueprint1's.

application.register_blueprint(bp2)
application.register_blueprint(bp1)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is working exactly as intended, although not as you expect.

Defining a template folder for a blueprint only adds the folder to the template search path. It does not mean that a call to render_template from a blueprint's view will only check that folder.

Templates are looked up first at the application level, then in the order blueprints were registered. This is so that an extension can provide templates that can be overridden by an application.

The solution is to use separate folders within the template folder for templates related to specific blueprints. It's still possible to override them, but much harder to do so accidentally.

app/
    blueprint1/
        templates/
            blueprint1/
                index.html
    blueprint2/
        templates/
            blueprint2/
                index.html

Point each blueprint at its templates folder.

bp = Blueprint('bp1', __name__, template_folder='templates')

When rendering, point at the specific template under the templates folder.

render_template('blueprint1/index.html')

See Flask issue #1361 for more discussion.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...