Django DRY - 如何在 Django 模板中扩展两个 .html 文件?
Posted
技术标签:
【中文标题】Django DRY - 如何在 Django 模板中扩展两个 .html 文件?【英文标题】:Django DRY - How to extend two .html files inside a Django Template? 【发布时间】:2021-02-03 23:53:49 【问题描述】:我想要什么?
我想在addstudents.html
内扩展cards/apps.html
,这样我就不需要多次编写代码。如何在 DJANGO 模板中扩展多个 .html
文件?
我遇到的错误
'extends' 在同一个模板中不能出现多次
怎么办?
注意:我不想使用
% include %
,因为情况/条件不合适。
您可能需要的一些信息...
内部卡片/apps.html
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">card_title</h6>
</div>
<div class="card-body">
% block card_body %
% endblock %
</div>
addstudents.html 内
% extends 'layouts/panel.html' %
% extends 'apps/card.html' %
% load static %
% block content %
% with card_title='My Card TITLE' %
% block card_body %
...SOME FORM, .... SOME PARAGRAPH
% endblock %
% endblock %
layouts/panel.html 里面有什么
layouts/panel.html
包含一些菜单和导航栏项[包括 CSS、引导程序和 JS 依赖项]。
apps/card.html
是什么?
apps/card.html
包含 HTML 和 Bootstrap CARD 的 code-sn-p。而且我不想多次编写此代码。这就是为什么我希望通过Django Template Tags
对其进行操作。
希望您能理解
【问题讨论】:
如果可以从两个基本模板扩展,你会如何期望 Django 合并两个基本模板?我认为您的用例需要使用include
指令。或者,您可以创建从第一个扩展的第二个基本模板,然后让您的模板扩展第二个(如果有意义)。
我想你是在说我将代码加载到 'layouts/panel.html'
中,这会使代码变得既垃圾又慢。
父模板只能有一个。如果你想在几个不同的地方渲染同一段 html,又不想重复,include 标签可以帮助你 - docs.djangoproject.com/en/3.1/ref/templates/builtins/#include 。你能解释一下为什么你不想使用它吗?
我已经告诉过你我不想使用包含。我需要在% block card_body %
中编写一些代码(如 HTML-Form)。我不能在% include %
内这样做。 Include 将加载 HTML 中的所有代码块,with
可用于传递一些不能满足我要求的变量。所以为此我想要一些像% block card_body %
include
正是@Selcuk 和 Erlond 提到的这个用例。您看到的冲突可以通过改进模板和布局来解决。这感觉就像an XY problem。
【参考方案1】:
我不认为这是直接可能的。但这里有一个解决方法。在处理addstudents.html
的视图中,将has_card
作为True
添加到上下文中。
views.py
def app_students(request):
# Your code
return render(request, 'addstudents.html', 'has_card': True)
layouts/panel.html
[...]
% if has_card %
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">card_title</h6>
</div>
<div class="card-body">
% block card_body %
% endblock %
</div>
</div>
% endif %
[...]
addstudents.html
% extends 'layouts/panel.html' %
% with card_title='My Card TITLE' %
% block card_body %
...SOME FORM, .... SOME PARAGRAPH
% endblock %
因此,如果 has_card
不存在,则不会有 card_body
块,但如果它确实作为真值存在,那么它会存在。
【讨论】:
'extends' 在同一个模板中不能出现多次 是的。仅扩展panel.html
,删除 card.html
或 app.html
或任何调用卡片设计的文件,如果您将 has_form
传递给您的视图,它应该可以工作。
@BishwasBhandari,你试过这个吗?它应该工作!【参考方案2】:
我不确定它是否符合您的需要。 一种方法是在不同模板之间稍微划分职责。 根据给定的信息,可以将引导程序/布局的内容放在cards/apps.html 中,并添加额外的块供孩子覆盖以处理表单和查看特定信息。
澄清可能解决问题的继承:
layouts/panel.html -> apps/card.html -> addtudents.html
apps/card.html
从 layout/panel.html
覆盖 block content
并添加由 addstudents.html
使用的其他块。
它也可以被看作是:addstudents.html extends card.html,它扩展了 panel.html。 Afaik 您可以根据需要进行多次扩展,但不能在同一个模板中使用两次。
cards/apps.html
% extends 'layouts/panel.html' %
% block content %
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">% block card_title %% endblock %</h6>
</div>
<div class="card-body">
% block card_body %
% endblock %
</div>
% endblock content %
addstudents.html
% extends 'apps/card.html' %
% block card_titleMy Card TITLE% endblock card_title%
% block card_body %
...SOME FORM, .... SOME PARAGRAPH
% endblock card_body %
还值得一提的是 block.super ,如果您需要渲染“父级”,它有时会非常有用。
【讨论】:
扩展% extends 'layouts/panel.html' %
怎么样
您可以多次扩展,但不能在同一个模板中扩展两次...在示例中给出了以下继承:layouts/panel.html' -> cards/apps.html -> addstudents。 html。有意义吗?以上是关于Django DRY - 如何在 Django 模板中扩展两个 .html 文件?的主要内容,如果未能解决你的问题,请参考以下文章
Django/Python DRY:使用 Q 对象和模型属性时如何避免重复代码
在多个 django 模板文件中显示相同 html 块的最佳 DRY 方法