Django:扩展还是包含?

时间:2010-02-24 01:15:27

标签: django include extends

我和我的朋友正在争吵。在我目前的Django项目中,我创建了一个名为menu.html的文件,其中包含一系列配置并格式化为列表的链接。我没有手动将菜单硬编码到每个页面中,而是使用以下Django / Python代码包含菜单:

{% include 'menu.html' %}

然而,我的朋友建议这是不正确的做法。他说我需要使用extends而不是include然后定义内容,如下所示:

{% extend 'menu.html' %}
{% block content %}
The rest of my content here.
{% endblock %}

这是一些额外的代码。我使用哪个真的很重要?我更愿意使用前者。

3 个答案:

答案 0 :(得分:13)

是的,这很重要。首先,extends只能作为文件的第一行出现。其次,include在解析堆栈上推送并弹出一个上下文对象,这意味着在include中的上下文中创建的值在返回时将超出范围。

我的规则是:创建base.html模板文件,用于定义网站的整体结构,并在关键区域周围使用宽松的{% block foo %}。然后你的所有其他模板extends基础(或者它自己扩展基础的东西)并根据需要替换这些块。

另一方面,

include适用于封装您可能需要在多个地方使用的内容,甚至可能在同一页面上。

<强>更新

我一直在使用我自己的template_tags库,这让我忘记了Django的模板语言在功能方面仍然存在重大差距。这里讨论的标签来自一个名为expr的早期django片段,我对其进行了大量编辑和扩展。例如,您可以说{% expr 'Fred' as name %}(或任何有效的Python表达式),它会将结果存储在当前Context 中的'name'插槽中。如果在included模板中发生这种情况,则会在退出模板文件时弹出name的值。

您可以使用{% with %}标记实现此目的,但expr为我提供了更大的灵活性,包括执行任意复杂的调用。最初出现这种情况时,必须创建复杂的缓存对象,这些对象需要在视图中无法完成的昂贵的DBMS交互,因此必须在模板本身中调用它们。

如果您需要深入了解,请给我发电子邮件(在我的个人资料中)。

答案 1 :(得分:3)

(他的朋友)

我的意思是定义一个base.html,这样你就可以继承几个通用部分的基本模板,这个包含doctype,html元素定义了3个内容和导航块以及可选区域来覆盖/插入脚本中的脚本/链接元素。

<!doctype>
<html>
<head>
{%block extrahead %} {%endblock %}
</head>
{%block nav %}
<nav>
  <ul>
    <li>home</li>
  </ul>
</nav>
<div id="content">
{% endblock %}
{%block content %}
{% endblock %}
</div>
</html>

然后您可以定义homepage.html

{% extends "base.html" %}

{% block content %}
homepage content
{% endblock %}
然后

homepage.html会有导航,因为它会扩展base.html

答案 2 :(得分:2)

在这种情况下,将菜单放在base.html并从中延伸似乎更有意义。

including非常适合拆分复杂模板并重复使用这些块。

比方说,您在网站的不同位置使用相同的列表样式,但是您向其发送其他查询集。只要你调用查询集一样,你只需要编写一次模板代码。

Here我对normal-和ajax-requests使用不同的模板。但是使用include让我重复使用两个模板中的大多数部分