Flask/Jinja多模板继承问题:跨模板无法继承Block内容
解决Jinja子模板Block无法覆盖Include模板中内容的问题
问题根源
Jinja的{% include %}是将目标模板内容静态插入到当前模板中,header.html里的test1 block属于base.html的上下文。而子模板MyPage.html继承base.html时,仅能覆盖base.html中直接定义的block,无法覆盖通过include引入的模板里的block,这就是你看到test1=为空的原因。
推荐解决方案
利用Jinja的self对象调用父模板的block,让include的模板能引用到子模板定义的内容:
- 修改
base.html,直接在include 'header.html'前定义test1block:
<!DOCTYPE html> <html> {% block test1 %}{% endblock %} {% include 'header.html' %} <body> <div class="container"> <h1 class="text-center my-4">{% block header %}{% endblock %}</h1> {% include 'menu.html' %} {% block content %}{% endblock %} </div> </body> {% include 'footer.html' %} </html>
- 修改
header.html,将原来的{% block test1 %}{% endblock %}替换为调用base中定义的block:
<head> ... <title>{% block title %}{% endblock %}</title> ... </head> test1={{ self.test1() }}
MyPage.html保持不变:
{% extends 'base.html' %} {% block test1 %}test1{% endblock %}
可选方案:变量传递法
如果不想用block,也可以通过变量传递内容:
- 修改
base.html,include header时传递变量:
<!DOCTYPE html> <html> {% block test1_content %}{% endblock %} {% include 'header.html' with test1_content=self.test1_content() %} <body> <div class="container"> <h1 class="text-center my-4">{% block header %}{% endblock %}</h1> {% include 'menu.html' %} {% block content %}{% endblock %} </div> </body> {% include 'footer.html' %} </html>
- 修改
header.html,使用变量输出内容:
<head> ... <title>{% block title %}{% endblock %}</title> ... </head> test1={{ test1_content or '' }}
MyPage.html定义变量对应的block:
{% extends 'base.html' %} {% block test1_content %}test1{% endblock %}
效果验证
修改完成后,访问/MyPage页面,会正确显示test1=test1,同时保留子模板的复用性,无需在base中重复编写内容。
内容的提问来源于stack exchange,提问作者Oleksandr Myronchuk
相关产品推荐
相关产品推荐

