创建可重用模板的Django方法是什么?
示例:假设我的很多网页都包含“最新消息”框并遵循DRY原则,我想定义一次并在其他页面中重复使用。我如何使用Django(或Jinja2)模板?
阅读Django's Template Documentation我得到的结论是,Django模板提供了“自上而下”的继承,其中子模板本身决定了它将嵌入哪个超模板:
<!-- Super-template (not valid, for illustration): -->
<html>
<head><title>Title</title></head>
<body>{% block content %}{% endblock %}</body>
</html>
<!-- Sub-template: -->
{% extends "base.html" %}
{% block content %}
<div class="latest-news">News</div>
{% endblock %}
那么在几个位置重用块(子模板)的技术是什么?
答案 0 :(得分:27)
重用模板片段最灵活的方法是define an inclusion_tag。您可以将参数传递给自定义标记,在Python中处理它们,然后退回到模板。 Direct inclusion仅适用于不依赖于周围环境的片段。
文档中的快速示例:
在app/templatetags/poll_extras.py
中注册带有装饰的标记:
from django import template
register = template.Library()
@register.inclusion_tag('results.html')
def show_results(poll):
choices = poll.choice_set.all()
return {'choices': choices}
在app/templates/results.html
:
<ul>
{% for choice in choices %}
<li> {{ choice }} </li>
{% endfor %}
</ul>
调用标签:
{% load poll_extras %}
{% show_results poll %}
答案 1 :(得分:12)
您要找的是来自Django docs的{% include "template.html"%}
。
答案 2 :(得分:10)
如果您需要使用{% block %}
,则只能通过{% extend %}
方法执行此操作。否则,您可以使用{% include 'some.html' %}
在多个位置包含一些HTML。
答案 3 :(得分:3)
非官方Django Reusable App Conventions建议使用这些块名称:
{% block title %}
{% block extra_head %}
{% block body %}
{% block menu %}
{% block content %}
{% block content_title %}
{% block header %} {% block footer %}
{% block body_id %} {% block body_class %}
{% block [section]_menu %} {% block page_menu %}
如果每个人都坚持这些惯例,它应该会使这个问题更容易。点击链接查看每个区块的描述。
答案 4 :(得分:1)
如其他答案所述,最简单的方法是直接包含:
{% include 'mytemplate.html' %}
可以使用
修改渲染模板的上下文(或更简单地说,是将变量传递给模板)。{% include 'mytemplate.html' with poll=poll %}
以传统民意调查为例,我要编写的模板为:
<div class="stylish-poll">
{% for choice in poll.choices %} <!-- poll is a template variable -->
{% include 'choice_template.html' with choice=choice %}
{% endfor %}
</div>
要知道的另一种可能有用的事情是,only
关键字可防止将模板变量poll
传递到'choice_template.html'
中,默认情况下该模板变量将被传递。如果您不希望选择模板有权访问{{ poll }}
,则include语句如下所示:
{% include 'choice_template.html' with choice=choice only %}
文档:https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include
答案 5 :(得分:0)
Aïe,我的错 - 答案在Django Reference中给出(并没有在上述Django Template Documentation中讨论过)......
所以:只需使用{% include sub_template_name %}
。
答案 6 :(得分:0)
使用{% include %}
标签的示例
card_template.html
中的include
标签将许多值传递给page1.html
card_template.html
<style>
.choices_div {
border-radius: 5rem;
}
.card-footer {
background-color: transparent;
border: transparent;
}
</style>
<div class="col mb-5 px-4">
<div class="card h-100 w-100 jumbotron choices_div {{ bg_color|default:'' }}">
<div class="card-body p-0">
<h3 class="card-title text-center">{{ card_title|capfirst }}</h3>
<ul class="card-text mt-3">
{% for c in card_body_list %}
<li>{{ c }}</li>
{% endfor %}
</ul>
</div>
<div class="card-footer text-center pt-4">
{% if get_post_request == 1 %}
<a class="btn btn-light" href="{{ href }}">{{ button_text }}</a>
{% else %}
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-light w-75" name="category"
value="{{ button_value }}">{{ button_text }}</button>
</form>
{% endif %}
</div>
</div>
</div>
page1.html
{% extends 'core/core.html' %}
{% block body %}
<div class="jumbotron bg-white">
<div class="container">
<div class="mb-5 text-center">
<h1>Choose user category</h1>
<h5>Once choosen, the user category cannot be changed</h5>
</div>
<div class="row row-cols-lg-2 justify-content-around">
{% for object in object_list %}
{% cycle 'bg_peacock' 'bg_sunset' 'bg_skin' 'bg_brown' as bg_color silent %}
{% include 'core/card_template.html' with card_title=object.category card_body_list=object.description get_post_request=2 button_text='Select' bg_color=bg_color button_value=object.id %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}
答案 7 :(得分:0)
尽管这个问题是多年前提出的,但无论如何我都会向您展示对我有用的方法。
base.html
在您的基本模板中,您需要定义您需要在其他模板中重用的所有块,
<html>
<head>
<meta name="description" content="{%block description%}{%endblock%}">
<meta name="keywords" content="{%block keywords%}{%endblock%}">
<title>{%block title%}{%endblock%}</title>
</head>
<body>
<!---other body stuff--->
{%block content%}
{%endblock%}
</body>
</html>
home.html
{%extends 'base.html'%}
<!--you can reuse all blocks here-->
{%block description%}Django reusable blocks, for every bage{%endblock%}
{%block keywords%}django,block, resuable,meta,title,{%endblock%}
{%block title%}django reuseable blocks for title, meta description and meta keywords{%endblock%}
{%block content%}
<div>
<h1> reuse blocks</h1>
</div>
{%endblock%}