Django模板继承 - 如何为不同的块使用相同的内容
Posted
技术标签:
【中文标题】Django模板继承 - 如何为不同的块使用相同的内容【英文标题】:Django template inheritance - How to use the same content for different blocks 【发布时间】:2015-04-05 00:25:58 【问题描述】:我的 django 模板中有以下结构
我有一个theme_base.html
,其他模板继承自:
现在,大多数页面的页眉和基础相同 page_title,所以我需要在我的普通模板中做这样的事情:
% block page_title_header %当前页面的页面标题% endblock % % block page_title_body %当前页面的页面标题% endblock %这不是 DRY 并且大多数时候我忘记更新page_title_header
:(
您能否推荐一种将页面标题(每个页面的标题不同,因此我不能使用默认值)传递给两个块的 DRY 方式?
更新:在 cmets 讨论后,我相信 % with % 模板标签将是我需要使用的,做这样的事情:
% 以“页面标题”为标题 % % block page_title_header % title % endblock % % block page_title_body % title % endblock % % endwith %不幸的是,上面的不起作用,标题没有传递给块!如果我删除 % block %
并执行类似
它会正常工作的。你知道可能是什么问题吗? TIA
【问题讨论】:
【参考方案1】:您可以在块中指定默认值,例如:
[...]
<title>% block page_title_header %Page title% endblock %</title>
[...]
<h1>% block page_title_body %Page title% endblock %</h1>
当您在普通模板中省略这些块时,将使用默认值。
【讨论】:
我知道这一点。问题是 每个 模板都有不同的标题!我会尝试改写我的问题以使其更清楚......【参考方案2】:试试:
<title>% block page_title_header %
% if somevar_title %
somevar_title
% else %
Default title
% endif %
% endblock %</title>
并将 somevar_title 放在您的上下文中。在您看来:
context = 'somevar_title': Page.objects.get(pk=something).title
return render(request, self.template_name, context)
您只需要记住在要使用该模板的每个视图的上下文中添加标题。 您还可以使用基于类的视图更新上下文:
class MyClass(TemplateView):
def get_context_data(self, **kwargs):
context = super(MyClass, self).get_context_data(**kwargs)
#get your title here...whatever you need it to be
context['somevar_title'] = Something_to_get_my_title
return context
然后,如果您从 slug 或某种可以以通用方式解决的方式获取标题,只需子类化 MyClass,您将在上下文中拥有变量。例如,使用 Page.objects.get(pk=kwargs.get('page_id'))
之类的东西就可以解决问题(不要忘记添加逻辑来处理无效的 id)。
【讨论】:
我已经想到了这一点(使用上下文变量),但这可能会为我的模板/视图添加 更多 工作,而不仅仅是重复标题(就像我现在所做的那样),因为我需要使用您提议的get_context_data
创建一个 PageTitleMixin
,不同之处在于我将使用 context['somevar_title'] = self.page_title 而不是 context['somevar_title'] = Something_to_get_my_title。对于从 PageTitleMixin
继承的每个 CBV,我需要添加一个 page_title
属性。这是一个很好的解决方案,但是我真的更喜欢只使用模板(如果可能的话)。
要仅使用模板,您需要某种方式在某些时候访问信息。它必须在数据库、url、某处。另外,就像我说的那样,只要您始终以相同的方式获得标题(即数据库中某个模型的某些字段),您就可以将 MyClass 子类化,它就会起作用。您不需要为每个视图定义 page_title。您将标题存储在哪里?
现在?在模板里面!每个模板/视图都有自己的标题,例如“配置文件详细信息”、“配置文件更新”等...这就是为什么我提到每个视图一个标题...
我的意思是,你不能计划神奇地得到它们,你一定想把它们从某个地方拿出来……某个模型,某个 url,某个地方……
实际上,正如我之前所说,我的大多数模板在模板中都有一个硬编码的标题。我需要写两次!这就是我想要避免的!【参考方案3】:
使用 block.super。示例:
% block page_title %
% with "foo" as title %
block.super
% endwith %
% endblock %
【讨论】:
以上是关于Django模板继承 - 如何为不同的块使用相同的内容的主要内容,如果未能解决你的问题,请参考以下文章