Overwriting a block within an `include`d template from an extended template

£可爱£侵袭症+ 提交于 2019-12-21 03:41:10

问题


I have the following:

base.html

<html>
    {% include 'header.html' %}
    <div>
    {% block content %}Default Content{% endblock %}
    </div>
</html>

header.html

<header>
     {% block logo %}Logo 1{% endblock %}
</header>

homepage.html

{% extend 'base.html' %}
{% block logo %}Logo 2{% endblock %}
{% block content %}Yap Yap Yap{% endblock %}

Essentially, this doesn't work. When I render the homepage.html I get:

<html>
    <header>Logo 1</header>
    <div>Yap Yap Yap</div>
</html>

but If I move the code in header.html into base.html (i.e. get rid of the include altogether) it works ok. Can anyone explain why this is the case?

I have a feeling it has something to do with the included templates getting rendered after their parents have been rendered?


回答1:


from the docs

The include tag should be considered as an implementation of "render this subtemplate and include the HTML", not as "parse this subtemplate and include its contents as if it were part of the parent". This means that there is no shared state between included templates -- each include is a completely independent rendering process.

so the subtemplate (header.html) is getting fully rendered and inserted into the parent template (base.html), meaning there is no concept of the block for the child template (homepage.html) to overwrite




回答2:


This is a known limitation that we hope be solved in a near future.

By the way, presuming that you have a more complex problem that you have mentioned, another work around for this is making header a block and than overriding this block with a new custom include.

base.html

<html>
    {% block header %}
        {% include 'header.html' %}
    {% endblock %}
    <div>
        {% block content %}Default Content{% endblock %}
    </div>
</html>

header.html

<header>
     {% block logo %}Logo 1{% endblock %}
</header>

homepage.html

{% extends 'base.html' %}

{% block header %}
    {% include 'homepage_header.html' %}
{% endblock %}

{% block content %}Yap Yap Yap{% endblock %}

homepage_header.html

{% extends 'header.html' %}

{% block logo %}Logo 2{% endblock %}



回答3:


I had a similar problem. I have a filtered table template which is of form

{% extends 'base.html' %}
{% include 'filtered_table.html' %}

where filtered_table.html is:

{% load render_table from django_tables2 %}
<div class="panel-body" >
  <form method='GET'>
  <div class="search-form" style="border: 1px solid #000000; background-color:#a3ffaf; overflow: auto;">
{% block render_form %}
    {% for field in filter.form %}
         {{ field.errors }}
         {{ field.label_tag }} {{ field }}
    {% endfor %}
{% endblock %}
    <input type='submit' value='Filter' />
    |
    Displaying {{ filter.qs.count }} of {{ filter.queryset.count }} {{ object_name }}s.
    |
    <a href='{{ request.path }}' >Clear</a> <p>
  </div>

{% if table %}
    {% render_table table %}
{% endif %}

</form>

</div>

I may want to specially hand-craft the form, for example by spelling out each field like this:

{% block render_form %}
{{ filter.form.field1.errors }}
{{ filter.form.field1.label_tag }}
{{ filter.form.field1 }}
<p>

{{ filter.form.field2.errors }}
{{ filter.form.field2.label_tag }}
{{ filter.form.field2 }} 
{% endblock %}

Unfortunately, because I can't do "extends" twice, I can't get my base layout and customize the filtered table. So the ugly (because breaks HTML structure in half) way to do this is to simply define begin_filtered_table.html and end_filtered_table.html. Then in the customized case I have two includes wrapping the customization, and for the uncustomized case, filtered_form.html is defined like this:

{% include "begin_filtered_table.html" %}

    {% for field in filter.form %}
         {{ field.errors }}
         {{ field.label_tag }} {{ field }}
    {% endfor %}

{% include "end_filtered_table.html" %}

This solves the problem at the expense of being gross. It would be much easier just to allow multiple extends.




回答4:


You cannot overwrite the logo from homepage.html because it's not defined in the base template itself.

The solution is, as you propose, to move the header.html code into base.html



来源:https://stackoverflow.com/questions/9034331/overwriting-a-block-within-an-included-template-from-an-extended-template

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!