Django 如何从另一个应用程序中包含模板?

75

在设置我的项目并努力使应用程序保持非依赖性时,我遇到了一个问题。我希望来自不同应用程序的所有模板都具有一致的页眉和页脚。以下是我的尝试:

myproject/
         base/
             templates/
                      header.html
                      footer.html
         app1/
             templates/
                      my_app1_page.html -> want to include 'header.html'
                                           and 'footer.html' from base app

假设还有许多其他应用程序也想要这样做。 这是可能的,并且/或者这是正确的方法吗?

3个回答

115
只要应用程序被包含在INSTALLED_APPS中,并且启用了来自应用程序目录的模板加载器,您就可以包含来自另一个应用程序的任何模板,例如:
{% include "header.html" %}

...因为你的模板直接放在应用程序的templates目录中。 通常为了避免名称冲突,最好使用:

app1/
    templates/
        app1/
            page1.html
            page2.html
app2/
    templates/
        app2/
            page1.html
            page2.html

并且 {% include "app1/page1.html" %} 或者 {% include "app2/page1.html" %} ...

但是:为了保持一致的外观和感觉,最好使用模板继承而不是包含。模板继承是 Django 模板系统中的非常好的功能之一,在大多数情况下,只要有意义就选择继承而不是包含。

我的建议:

  • 为您的项目创建一个基本模板("base.html" 是默认约定),其中包含头部和底部以及一个{%block content%} 用于主要内容。
  • 让其他模板从 base.html 继承 {% extends "base.html" %} 并覆盖内容部分

请参阅此问题的另一个响应以获取文档链接


4
对于那些可能认为包含函数是一种不好的实践的 Django 新手,我想稍微扩展一下建议:虽然我同意利用继承是很好的,但是说它比包含选项更好并不完全正确。它只是有不同的用途。它是处理较小的 HTML 片段的好工具(就像 WordPress 中的模块/小部件)。例如,您可能想在第二个应用程序中列出博客的所有类别,如果没有 {% include %} 选项,您可能会意识到您必须在两个应用程序中重新编写相同的代码。 - PiWo

11

虽然您可以使用include标签并指定绝对路径来实现此目的,但在Django中正确的方式是使用模板继承


3
如果我有一些模型和部分模板来呈现这些模型,比如地址、事件,那么我认为在这种情况下将它们包含进来是有意义的。 - quapka
继承绝不是导入的正确替代方式。 - E.Serra

3
如果你使用 "$ django-admin startproject project" 开始一个项目,会创建一个名为 "project-folder-name" 的文件夹,即 project/。在添加一些应用程序并将其添加到 "settings.py" -> INSTALLED_APPS=[..., app1, app2] 中,并在项目目录中创建一个 templates 文件夹后,我的结构如下:
project/
    project/
        templates/
            base.html
    app1/
        templates/
            app1/
                page1.html
                page2.html
    app2/
        templates/
            app2/
                page1.html
                page2.html

在模板 app1/template/page1.html 中,我写了以下内容:

{% extends 'base.html' %}

结果出现了 "TemplateDoesNotExist at /" 错误信息。

然后我添加了另一个名为 "core" 的应用程序,并将 base.html 添加到了模板文件夹中(+ 在 settings.py 中编辑 INSTALLED_APPS),现在我的结构如下:

project/
    project/
        templates/    (unused)
            base.html (not seen)
    core/
        templates/
            base.html
    app1/
        templates/
            app1/
                page1.html
                page2.html
    [...]

现在错误信息已经消失,找到了base.html和templates/app1/page1.html:

{% extends 'base.html' %}

您可以像这样更改文件夹结构:

    core/
        templates/
            core/
                base.html

那么你需要更改模板 app1/page1.html 为:

{% extends 'core/base.html' %}

另外,您还可以将“your-project-name”添加到此说明中的“project”,并将其放入您的设置文件中,如下所示:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'project', # your project name main folder
    'core',
    'App1',
    'App2',
]

现在Django也会找到project/templates/base.html了。不过我不确定这种解决方案是否被推荐使用。

project/
    project/
        templates/    
            base.html (now it is found)

顺便说一句,谢谢(我的投票还没有算),如果这个回答在某种程度上是清晰易懂的,请评论我。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接