如何在扩展另一个文件的 django 模板中使用带有动态内容的 html 块片段?

Posted

技术标签:

【中文标题】如何在扩展另一个文件的 django 模板中使用带有动态内容的 html 块片段?【英文标题】:how do I use html block snippets with dynamic content inside a django template that extends another file? 【发布时间】:2011-02-09 20:45:51 【问题描述】:

有人可以帮我找出在 Django 模板中实现以下目标的方法(参见下面的 sn-ps)吗?我知道你不能使用多个扩展,但我是 django 的新手,我不知道这样的东西的正确语法。我希望能够做到这一点,这样我就可以出于 css 的原因使用我的嵌套 div 布局,而不必每次都像这样键入它并冒着打字错误的风险。换句话说,我希望能够有一个页面模板扩展我的 base.html 文件,然后使用动态模板内容的 html sn-ps(即循环或其他模板逻辑设备的模板,而不仅仅是我从我设置的上下文变量视图控制器)。


编辑: 我希望能够在每一列中以任意方式显示任意内容。例如,我希望能够在一列中显示 ul 图像,然后在同一页面上显示另一组显示数据表的列。这是我输入的一个示例: example of alot of random columns


我意识到示例图片具有从 django web 测试器输出生成的所有文本,但每个库应该能够具有随机内容。它们应该是可嵌套的。这可以使用默认的 django 模板语言吗?

------------------------------------------------------------
base.html
------------------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title>% block title %Title% endblock %</title>
    </head>
    <body>
        <div class="wrapper">
            <div class="header">
                This is the common header
            </div>
            <div class="nav">
                This is the common nav              
            </div>
            % if messages %
                <div class="messages">
                    <ul>
                        % for message in messages %
                        <li% if message.tags % class=" message.tags "% endif %> message </li>
                        % endfor %
                    </ul>
                </div>
            % endif %
            <div class="content">
                % block content %Page Content% endblock %
            </div>
            <div class="footer">
                This is the common footer
            </div>
        </div>
    </body>
</html>
------------------------------------------------------------
columnlayout2.html
------------------------------------------------------------
<div class="twocol container2">
    <div class="container1">
        <div class="col1">
            % block twocol_col1 %% endblock %
        </div>
        <div class="col2">
            % block twocol_col2 %% endblock %
        </div>
    </div>
</div>

------------------------------------------------------------
columnlayout3.html
------------------------------------------------------------
<div class="threecol container3">
    <div class="container2">
        <div class="container1">
            <div class="col1">
                % block threecol_col1 %% endblock %
            </div>
            <div class="col2">
                % block threecol_col2 %% endblock %
            </div>
            <div class="col3">
                % block threecol_col3 %% endblock %
            </div>
        </div>
    </div>
</div>

------------------------------------------------------------
page.html
------------------------------------------------------------
% extends "base.html" %

% block content %

    % extends "columnlayout2.html" %
        % block twocol_col1 %twocolumn column 1% endblock %
        % block twocol_col2 %twocolumn column 2% endblock %

    % extends "columnlayout3.html" %
        % block threecol_col1 %threecol column 1% endblock %
        % block threecol_col2 %threecol column 2% endblock %
        % block threecol_col3 %threecol column 3% endblock %

% endblock %

------------------------------------------------------------
page.html output
------------------------------------------------------------
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title>Title</title>
    </head>
    <body>
        <div class="wrapper">
            <div class="header">
                This is the common header
            </div>
            <div class="nav">
                This is the common nav              
            </div>
            <div class="content">
                <div class="twocol container2">
                    <div class="container1">
                        <div class="col1">
                            twocolumn column 1
                        </div>
                        <div class="col2">
                            twocolumn column 2
                        </div>
                    </div>
                </div>
                <div class="threecol container3">
                    <div class="container2">
                        <div class="container1">
                            <div class="col1">
                                threecol column 1
                            </div>
                            <div class="col2">
                                threecol column 2
                            </div>
                            <div class="col3">
                                threecol column 3
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="footer">
                This is the common footer
            </div>
        </div>
    </body>
</html>

【问题讨论】:

听起来像inclusion tags 是你所追求的。 【参考方案1】:

我同意丹尼尔的观点,包含标签可能是您所追求的,我认为您误解了它们和% extends %

如果您的内容是静态的或在上下文中,您可以使用 % include % 块,如

% block content %
    % include "columnlayout2.html" %
    % include "columnlayout3.html" %
% endblock %

这样您就可以将所需的内容存储在 two_columns 和 three_columns 之类的内容中并进行渲染

------------------------------------------------------------
columnlayout2.html
------------------------------------------------------------
<div class="twocol container2">
    <div class="container1">
        <div class="col1">
             two_columns[0] 
        </div>
        <div class="col2">
             two_columns[1] 
        </div>
    </div>
</div>

或者你可以在 page.html 中使用包含标签

编辑

版主需要在不同页面上呈现具有不同结构(不仅仅是内容)的 HTML,因此您可以执行诸如“嵌套”包含标记调用之类的操作。

% block content %
    % show_two_columns two_columns %
    % show_three_columns three_columns %
% endblock %

模板标签

@register.inclusion_tag("columns/two_columns.html")
def show_two_columns(columns):
    return 'columns': columns

two_columns.html

<div class="twocol container2">
    <div class="container1">
        <div class="col1">
            % render_column columns[0] %
        </div>
        <div class="col2">
            % render_column columns[1] %
        </div>
    </div>
</div>

然后你可以做任何你需要的逻辑来改变你想在 render_column 包含标签和它使用的模板中显示的内容。我希望我能说更多,但它非常具体到列内容所依赖的内容以及在每种情况下的不同之处。

【讨论】:

好的。我将此标记为答案。您如何操作通过 page.html 中的包含过滤器传递的列表/查询集/数据?我希望能够在几个不同的页面模板中使用列 sn-ps,因此通过包含过滤器传递的数据已经需要格式化为 html。 啊,我明白了。确实,您不想在视图中构造任何 HTML。 HTML 每次都完全不同吗? 是的... =/ 这就是让我头疼的原因。

以上是关于如何在扩展另一个文件的 django 模板中使用带有动态内容的 html 块片段?的主要内容,如果未能解决你的问题,请参考以下文章

我们可以在 django 的单个 html 模板中扩展多个 html 吗?如果可以,那么如何?

如何在另一个标签中使用 Django 模板标签?

Django DRY - 如何在 Django 模板中扩展两个 .html 文件?

如何更改扩展基本模板的 Django HTML 视图文件?

在 Django 中,如何从扩展的 HTML 模板中链接静态文件?

Django - 如何将 javascript 变量从另一个文件加载到模板