【问题标题】:Django: Extends or Include?Django:扩展还是包含?
【发布时间】:2010-02-24 01:15:27
【问题描述】:

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

{% include 'menu.html' %}

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

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

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

【问题讨论】:

    标签: django include extends


    【解决方案1】:

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

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

    另一方面,include 非常适合封装您可能需要在多个地方使用的东西,甚至可能在同一页面上。

    更新:

    我一直在使用我自己的 template_tags 库,以至于我忘记了 Django 的模板语言在功能上仍然存在重大差距。这里有问题的标签来自一个名为expr 的早期django sn-p,我对其进行了大量编辑和扩展。例如,您可以说{% expr 'Fred' as name %}(或任何有效的 Python 表达式),它会将结果存储在当前上下文中的“名称”槽中。如果这发生在 included 模板中,name 的值将在退出模板文件时弹出。

    您可以使用{% with %} 标签来实现这一点,但expr 给了我更大的灵活性,包括进行任意复杂的调用。这最初是在创建复杂的缓存对象时出现的,这些对象需要昂贵的 DBMS 交互,而这些交互无法在视图中完成,它们必须在模板本身中调用。

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

    【讨论】:

    • 你能用一个例子解释一下吗:value created in the context while in the include will go out of scope when it returns
    • ad 更新:哦,你在 Django 中拥有了几乎所有的 Python!就像在 Cheetah 或 Web2py 中一样!太好了!
    【解决方案2】:

    (他的朋友)

    我的真正意思是定义一个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

    【讨论】:

      【解决方案3】:

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

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

      假设您在站点的不同位置使用相同的列表样式,但您向它发送了其他查询集。只要你调用querysets一样,你只需要写一次模板代码。

      Here 我对普通请求和 ajax 请求使用不同的模板。但是使用 include 让我可以重用两个模板中的大部分内容

      【讨论】:

        猜你喜欢
        • 2011-11-28
        • 1970-01-01
        • 2010-11-27
        • 1970-01-01
        • 2013-01-19
        • 2014-07-27
        • 1970-01-01
        • 2012-02-26
        • 2023-04-05
        相关资源
        最近更新 更多