【问题标题】:Jinja2 Multi-level template inheritance issueJinja2 多级模板继承问题
【发布时间】:2017-09-13 15:23:35
【问题描述】:

我在一个Django App中有以下三个文件,模板引擎是Jinja2

skeleton.html

<head>
    {% block head_content %}
        <meta charset="utf-8">
        <title> {% if page_title %} {{ page_title }} | {% endif %} Bhargavi Books & Stationery </title>
        <link rel="stylesheet" href="{{ static("css/semantic.min.css") }}">
        <link rel="stylesheet" href="{{ static("Icons/font-awesome.min.css") }}">
    {% endblock head_content %}
</head>

<body>
    <div id="navigation">
    {% block navigation %}
        <div class="ui three item menu">
          <a class="active item">Home</a>
          <a class="item">New Bill</a>
          <a class="item">View Bills</a>
        </div>
    {% endblock navigation %}
    </div>

    <div id="frame">
        {% block frame_content %}
            <p> Body content goes here. Body for {{ content_name }}</p>
        {% endblock frame_content %}
    </div>

    <div id="app">
        {% block app_content %}
            <p> APP content goes here. Body for {{ content_name }}</p>
        {% endblock app_content %}
    </div>

    {% block scripts %}
        <script src="{{ static("js/jquery.js") }}"></script>
        <script src=" {{ static("js/semantic.min.js") }} "></script>
    {% endblock scripts %}
</body>

base.html

{% extends "skeleton.html" %}
{% from "macros/globalmacros.html" import
            SUIIconList,SUISimpleList,
            SUIImageLabel,SUILabel,
            SUIActionInput,SUILabeledInput,SUIInput,
            SUIDimmableActionCard,SUICard,
 %}


{% block frame_content %}
Frame Content
{% endblock frame_content %}

{% block scripts %}

{{ super() }}
<script src=" {{ static("js/globalmacros.js") }} "></script>

{% endblock scripts %}

dashboard.html

{% extends "base.html" %}

<div>
{% block body_content %}
Body 3
{% endblock body_content %}
</div>

<div>
{% block app_content %}

DASHBOARD

{% endblock app_content %}
</div>

在此设置中,Jinja 在最后一页中呈现除“仪表板”之外的所有内容。但是,当我在“base.html”中添加一个空块时,就像这样..

{% block app_content %}

App content Goes here...

{% endblock app_content %}

在最终模板中,打印“DASHBOARD”。这是Jinja的一些怪癖吗?这种行为在任何文档中都有定义吗??

【问题讨论】:

    标签: django python-3.x templates jinja2


    【解决方案1】:

    我了解您的问题:您有模板 A、模板 B(扩展模板 A)和模板 C(扩展模板 B)。模板 A 中定义了一个块,但它不会显示在使用模板 C 的页面中,除非您在模板 B 中定义该块。如果您这样做,然后有问题的块出现。

    首先:您的理解是正确的,这不是 Jinja 模板层次结构应该如何工作的。其次,我没有遇到您的问题(但发现了一个不同的问题),并且我已经构建了一个证明来证明这一点。这是我所做的(同样,使用 Python 3 和 Django 1.11):

    $ python startproject myapp
    

    myapp/myapp/settings.py文件中,我更新了模板引擎:

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.jinja2.Jinja2',
            'DIRS': [
                os.path.join(BASE_DIR, 'myapp/templates') # hack / should add `myapp` to INSTALLED_APPS instead
            ],
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    

    myapp/myapp/urls.py中,我创建了一个虚拟视图函数和路由:

    from django.conf.urls import url
    from django.shortcuts import render_to_response
    
    def home(request):
        return render_to_response('dashboard.html')
    
    urlpatterns = [
        url(r'^$', home),
    ]
    

    最后,我建立了这些模板,但我删除了导入宏的调用,以及 static() 的所有实例。

    这是 myapp/myapp/templates/skeleton.html 文件:

    <!doctype html>
    <html lang="en">
    <head>
      {% block head_content %}
        <meta charset="utf-8">
        <title> {% if page_title %} {{ page_title }} | {% endif %} Bhargavi Books & Stationery </title>
      {% endblock head_content %}
    </head>
    
    <body>
    <div id="navigation">
      {% block navigation %}
        <div class="ui three item menu">
          <a class="active item">Home</a>
          <a class="item">New Bill</a>
          <a class="item">View Bills</a>
        </div>
      {% endblock navigation %}
    </div>
    
    <div id="frame">
      {% block frame_content %}
        <p> Body content goes here. Body for {{ content_name }}</p>
      {% endblock frame_content %}
    </div>
    
    <div id="app">
      {% block app_content %}
        <p> APP content goes here. Body for {{ content_name }}</p>
      {% endblock app_content %}
    </div>
    
    {% block scripts %}
    {% endblock scripts %}
    </body>
    </html>
    

    这是 myapp/myapp/base.html 文件:

    {% extends "skeleton.html" %}
    
    {% block frame_content %}
      Frame Content
    {% endblock frame_content %}
    
    {% block scripts %}
      {{ super() }}
    {% endblock scripts %}
    

    这是 myapp/myapp/templates/dashboard.html 文件:

    {% extends "base.html" %}
    
    <div>
      {% block body_content %}
        Body 3
      {% endblock body_content %}
    </div>
    
    <div>
      {% block app_content %}
        DASHBOARD
      {% endblock app_content %}
    </div>
    

    这是在我的浏览器中查看该页面后的输出:

    <!doctype html>
    <html lang="en">
    <head>
      <meta charset="utf-8">
      <title> Bhargavi Books & Stationery </title>
    </head>
    
    <body>
    <div id="navigation">
      <div class="ui three item menu">
        <a class="active item">Home</a>
        <a class="item">New Bill</a>
        <a class="item">View Bills</a>
      </div>
    </div>
    
    <div id="frame">
      Frame Content
    </div>
    
    <div id="app">
      DASHBOARD
    </div>
    </body>
    </html>
    

    由于这一切都按预期工作*,我的结论是您可能对base.html 模板文件有问题。也许它无法导入您的宏,并且随后行为不正确?我注意到那里有一个逗号,我不确定这是否有问题。我建议以上面的代码为起点,然后慢慢将我剥离的部分添加回来,也许问题会变得可见/可以理解。

    *我发现奇怪的一件事,我不明白:body_content 块在我的输出中完全丢失,除非我在 skeleton.html 模板中定义该块。如果我在 base.html 模板中定义它就行不通,这对我来说似乎是错误的,因为那时我们并没有真正扩展第二个模板 (base.html)... 所以那里确实那里似乎有些奇怪...但是我无法遇到您描述的原始问题,因此至少在特定方面这可能会有所帮助。

    【讨论】:

      猜你喜欢
      • 2010-12-30
      • 2016-01-19
      • 2015-04-14
      • 2017-05-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多