为什么Django的原始作者包含标签?

Dom*_*ger 9 django django-templates

在Jacob Kaplan-Moss的优秀Google技术讲座中,Jacob表示include尽管之前存在教条主义的反对意见,他们还增加了对模板标签的支持,并表示人们不应该使用它.

有谁知道为什么?快速搜索没有显示任何可以解释原因的内容.现在修复的票证中没有任何相关内容,其中include添加了对标签的支持.我大量使用包含标签以避免重复自己,这似乎是一个好主意,但也许我错过了一些核心原因,为什么那些知道认为它是坏的.

Ben*_*mes 9

我想他希望通过继承(使用extends)而不是通过组合来鼓励模板重用.也许这意味着如果你不能以这种方式组织你的模板,那么教条主义的观点是你的网站组织得很糟糕.(例如,如果您正在重复使用导航菜单,它是否应该始终位于页面结构中的相同位置?为什么每个页面都要决定放置它的位置?)

顺便说一句,使用include并没有太大帮助你保持DRY,因为包含的模板所需的任何上下文必须从使用它的所有视图传递.

相比之下,使用自定义包含模板标记允许您在包含标记的位置执行任意Python代码,而不是在视图中执行(或者通过将其推送到模型中以使其更容易在模板中访问).

作为一个简单的例子,我想展示用户的头像列表.使用include,它看起来像这样:

{% for user in users %}
    {% with user.gravatar_url as avatar_url %}
        {% include "foo/bar/avatar.html" %}
    {% endwith %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

使用自定义标记:

{% for user in users %}
    {% gravatar user.email %}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)

使用自定义包含标记意味着Gravatar散列逻辑不再是User模型的关注点,也不是视图函数的关注点.


这就是说,我认为在某些情况下你不可避免地在多个模板的上下文中有类似的数据,你不需要做任何花哨的事情,你只想显示它的一些属性,所以你不想写一个函数让它工作.

例如,我写了一个博客应用程序(谁没有?),它有两种类型的归档视图:基本顺序,每页X-posts和每月归档视图.两个模板显然都在其上下文中有一个帖子列表,两者都使用完全相同的摘要模板片段来显示每个帖子的标题和摘录,但每个模板在略有不同的上下文中显示它们.所以我用过:

{# in archive_index.html #}
{% extends "base.html" %}

{# some stuff specific to sequential archives here #}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{# probably more stuff specific to sequential archives #}
Run Code Online (Sandbox Code Playgroud)

和...

{# in archive_monthly.html #}
{% extends "base.html" %}

{# some stuff specific to monthly archives here #}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{# probably more stuff specific to monthly archives #}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,组合似乎比继承更有意义.事实上,一开始很难想象继承在这里是如何起作用的.嗯,它仍然可能:

{# in base_archive.html #}
{% extends "base.html" %}

{% block archive_header %}{% endblock %}

{% for post in posts %}
    {% include "post_summary.html" %}
{% endfor %}

{% block archive_pagination %}{% endblock %}
Run Code Online (Sandbox Code Playgroud)

现在,两个不同的档案扩展了这一点,只是将他们独特的东西注入到块中:

{# in archive_monthly.html #}
{% extends "base_archive.html" %}

{% block archive_header %}
    <h1>Archive for {{ month }}</h1>
{% endblock %}

{% block archive_pagination %}
    {# previous/next month links here #}
{% endblock %}
Run Code Online (Sandbox Code Playgroud)

我会想象archive_index.html看起来像(无疑是无聊的)读者的练习.

唷!想出一种使用组合和继承来做同样事情的方法感觉很聪明,但是后者只是向后弯腰以符合Jacob Kaplan-Moss提到的教条吗?

刚观看了视频(是的,所有1小时5分钟的时间,我完全可以回答这个问题),我不认为雅各布会受到极大的打扰.这听起来像一个袖手旁观的评论,也许是你应该首先考虑哪种技术的参考.