我正在寻找在django中清理模板的方法。一个简单的解决方案是将其分解为多个模板,但我们不希望这样做。
我们基本上有以下
{%if data.some_state %}
Display some markup
{% else %}
{%if data.some_state_2 %}
State 2 different html view
{% else %}
{%if data.process_data %}
Display some list of data
{% else %}
No Data to display!
{% endif %} <!-- if data.process_data-->
{% endif %} <!-- if data.some_state_2 -->
{% endif %} <!-- if data.some_state -->
这非常令人困惑,难以阅读。如果我可以在“函数”中执行此操作,我将使用if / else if或return。
模板语言中有没有办法做类似的事情(stop_processing_template告诉模板我们完成了......):
{%if data.some_state %}
Display some markup
{% endif %}
{% django_stop_processing_template %}
{%if data.some_state_2 %}
State 2 different view
{% endif %}
{% django_stop_processing_template %}
{%if data.process_data %}
Display some list of data
{% endif %}
{% django_stop_processing_template %}
No data provided !
答案 0 :(得分:4)
我不确定你的停止处理模板逻辑会做什么;但是更简洁的方法是编写一个自定义标记,它接受你的参数,然后只返回与你的变量相关的HTML。这样您就可以移除if/else
循环,而是使用简单的{% do_stuff %}
标记替换所有循环。
修改的
这是一个非常简单的实现,可以让您了解逻辑将如何发展。
首先,您为每个变体创建模板,并将它们存储在django可以找到的地方。
然后,一个简单的标签,呈现您想要的确切模板(这是未经测试的,伪造的):
from django import template
from django.db.models import get_model
register = template.Library()
class ProcessData(template.Node):
def __init__(self, var_name):
self.obj = get_model(*var_name.split('.'))
def render(self, context):
if self.obj.some_state:
t = template.loader.get_template('some_markup_template.html')
result = 'something'
else:
if self.obj.some_state_2:
t = template.loader.get_template('some_different_html_view.html')
result = 'something'
else:
if self.obj.process_data:
t = template.loader.get_template('some_list_data.html')
result = 'something'
else:
t = template.loader.get_template('no_data.html')
result = 'something'
return t.render(Context({'result': result}, autoescape=context.autoescape))
@register.tag
def process_data(parser, token):
try:
tag_name, arg = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError("%r tag requires arguments" % token.contents.split()[0])
return ProcessData(arg)
最后,在您的模板中:
{% load my_tags %}
{% process_data data.mymodel %}
答案 1 :(得分:3)
您可以使用jinaj2来模板化该视图(或整个项目),它支持if
/ elif
/ else
分支:
{% if data.some_state %}
Display some markup
{% elif data.some_state_2 %}
State 2 different view
{% elif data.process_data %}
Display some list of data
{% endif %}
答案 2 :(得分:2)
虽然我认为@burhan's方法更好,但您也可以通过使用自定义标记来执行您想要做的事情,该标记将上下文变量设置为布尔值,而最外层的其他部分也可以转换为if标记
#Set a context variable nodata to True
{% setnodata True %}
{%if data.some_state %}
Display some markup
#Set context variable nodata to False
{% setnodata False %}
{% endif %}
{%if data.some_state_2 %}
State 2 different view
#Set context variable nodata to False
{% setnodata False %}
{% endif %}
{%if data.process_data %}
Display some list of data
#Set context variable nodata to False
{% setnodata False %}
{% endif %}
{% if nodata %}
No data provided !
{ % endif %}
setnodata
自定义标记只是将上下文变量nodata
设置为True或False,具体取决于参数。
答案 3 :(得分:1)
今天我遇到了同样的问题。 我发现这个标签 {%verbatim%} {%endverbatim%} 。这适用于Django1.5 + 一个例子:
{% verbatim %}
<div class="entry">
<h1>{{ title }}</h1>
<div class="body">
{{ body }}
</div>
</div>
{% endverbatim %}
您还可以在下方查看更多详情: