【问题标题】:Stack overflow when inheriting from base (master) template从基本(主)模板继承时堆栈溢出
【发布时间】:2016-05-15 22:16:28
【问题描述】:

我想扩展access_control 块以添加身份验证菜单链接。我不想覆盖整个 master.html 模板,所以我创建了 templates/admin/mymaster.html 文件,内容如下:

{% extends 'admin/master.html' %}
{% block access_control %}
    {{ super() }}
        <ul class="nav navbar-nav navbar-right">
            <...>
        </ul>
{% endblock %}

现在我有: 我究竟做错了什么? 最近,我以同样的方式覆盖了 admin/index.html:

{% extends 'admin/master.html' %}
{% block body %}
  <p>Here I'm going to display some data.</p>
{% endblock %}

而且效果很好。

MCVE:

from flask import Flask, redirect, url_for
from flask.ext.admin.base import MenuLink, Admin, BaseView, expose

app = Flask(__name__, template_folder='templates')

@app.route('/')
def index():
    return '<a href="/admin/">Click me to get to Admin!</a>'

flaskadmin = admin.Admin(name='Flasky', template_mode='bootstrap3', 
                   base_template='admin/mymaster.html')

flaskadmin.init_app(app)

# Start app
app.run(debug=True)

【问题讨论】:

  • 不应该有父 (),因为在 django 模板中,该方法已经可以调用。你试过只使用{{ block.super }}吗?
  • jinga2中如果要扩展block应该有super(),反正没关系,super没有作用,因为是继承问题。
  • 你应该在问题中真正提到 jinja2 以避免混淆。
  • 很公平,一旦我单击链接,很明显它是烧瓶 + jinja2。我之前没用过flask-admin,希望有经验的人帮忙
  • 该代码没有重现问题... WTForms==2.1,Flask-Admin==1.4.0。也有错误。 flaskadmin 行中的 admin.Admin 应该是 Admin 吗?

标签: python html flask jinja2 flask-admin


【解决方案1】:

我认为问题在于这一行,它旨在创建自定义基础模板。

flaskadmin = admin.Admin(name='Flasky', template_mode='bootstrap3', 
                   base_template='admin/mymaster.html')

见:https://github.com/flask-admin/flask-admin/blob/master/flask_admin/base.py#L490-L491

:param base_template:
    Override base HTML template for all static views.
    Defaults to `admin/base.html`.

在我看来,这不是你想要做的。如果您将应用程序代码更改如下,则不会发生递归问题。

flaskadmin = Admin(name='Flasky')

据我所知,如果你想覆盖基本模板,你覆盖的是 admin/base.html 而不是 admin/master.html

例如:

.
├── app.py
└── templates
    └── admin
        ├── mybase.html
        └── mymaster.html

app.py

from flask import Flask
from flask.ext.admin.base import Admin

app = Flask(__name__)

@app.route('/')
def index():
    return '<a href="/admin/">Click me to get to Admin!</a>'

flaskadmin = Admin(name='Flasky', base_template='admin/mybase.html')
flaskadmin.init_app(app)

if __name__ == '__main__':
    app.run(debug=True)

templates/admin/mybase.html

{% extends 'admin/base.html' %}

templates/admin/mymaster.html

{% extends 'admin/master.html' %}
{% block access_control %}
    {{ super() }}
    <ul class="nav navbar-nav navbar-right">
       <li>One</li>
       <li>Two</li>
    </ul>
{% endblock %}

【讨论】:

  • 我认为 Flask-admin 文档有点混乱:You can also override the **master** template, but then you need to pass your own template name to the Admin constructor: admin = Admin(app, base_template='my_master.html') github.com/mrjoes/flask-admin/blob/master/doc/…
【解决方案2】:

Flask-admin 文档有点混乱,因为它告诉你:

你也可以覆盖主模板,但是你需要通过 您自己的模板名称到 Admin 构造函数:

admin = Admin(app, base_template='my_master.html')

Flask-admin 使用代理模板,命名为 master.html,只包含以下一行:

{% extends admin_base_template %}

当我们将 base_template 传递给我们的 Admin 构造函数时,admin_base_template 变量将被我们的新 my_master/my_base 模板覆盖,因此我们不能只从它继承,否则会导致循环继承和堆栈溢出。我们应该继承 admin/base.html,而不是从 admin/master 继承。这样,我的解决方案就变成了:

<-- admin/mymaster.html -->
{% extends 'admin/base.html' %}
{% block access_control %}
    {{ super() }}
        <ul class="nav navbar-nav navbar-right">
            <...>
        </ul>
{% endblock %}

现在您只需从 admin/master.html 继承所有模板(和以前一样),因为它指向新的 base/mymaster

【讨论】:

  • "我们应该继承 admin/base.html。"这就是我告诉你的。 “你覆盖 admin/base.html 而不是 admin/master.html”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-16
  • 2019-05-18
  • 1970-01-01
  • 2021-11-05
  • 2013-10-30
  • 2012-01-19
  • 2021-05-28
相关资源
最近更新 更多