Django模板 - 停止处理模板
我想找一种方法来清理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或者返回值。
在模板语言中,有没有办法做类似的事情(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 !
4 个回答
2
虽然我觉得 @burhan的 方法更好,但你也可以通过使用一个自定义标签来实现你想要的功能。这个自定义标签会设置一个上下文变量为布尔值(也就是真或假),然后最外层的 else 部分也可以改成 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)。
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 %}