从基本(主)模板继承时发生堆栈溢出

Stack overflow when inheriting from base (master) template

我想扩展 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)

我认为问题出在这一行,它的意思是创建自定义基础模板。

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')

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

{% extends admin_base_template %}

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

<-- 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