在这里,我可能会使用模板标签。 我曾经遇到过类似的情况,即在同一页上以不同格式多次呈现日历信息。 我处理的方法是将查询到的数据传递到请求上下文中,然后只需将该查询集用作模板标记的参数即可。 结果是你可以得到像这样的模板语法:
视图
def my_view(request, *args, **kwargs):
yearly_sales_qs = SaleRecord.objects.filter(param=value)
monthly_sales_qs = SalesRecord.objects.filter(param=foo)
return render_to_response( ..., locals(), ... )
模板
{% load data_tags %}
<div class="year">
{% render_data_table for yearly_sales_qs %}
{% render_bar_chart for yearly_sales_qs %}
</div>
<div class="month">
{% render_data_table for monthly_sales_qs %}
{% render_bar_chart for monthly_sales_qs %}
</div>
那么如何制作这样的东西呢?首先查看 Django 文档中关于 自定义模板标签和过滤器 的内容。这比 Django 其余部分更难入手,但一旦掌握了它,就会变得非常容易。
- 在您的应用程序文件夹中创建一个名为“templatetags”的文件夹。
- 在该新文件夹中创建一个空白文件“__init__.py”
- 将 templatetags 文件夹的位置添加到
settings.py
中的 TEMPLATE_DIRS
设置中(如果尚未存在)。
因为我们将制作多个这样的内容,所以我们可以制作一个基础模板标签,我们将从中继承封装我们基本功能...
data_tags.py(存储在 templatetags
文件夹中)
class DataForTag(tempalte.Node):
@classmethod
def handle_token(cls, parser, token, template):
tokens = token.contents.split()
if tokens[1] != 'for':
raise template.TemplateSyntaxError("First argument in %r must be 'for'" % tokens[0])
if len(tokens) == 3:
return cls(queryset=parser.compile_filter(tokens[2]), template=template)
else:
raise template.TemplateSyntaxError("%r tag requires 2 arguments" % tokens[0])
def __init__(self, queryset=None, template=None):
self.queryset = queryset
self.template = template
def render(self, context):
return render_to_string(self.template, {'queryset':self.queryset})
然后我们可以创建个体标签,用来处理我们需要的任何内容...
@register.tag
def render_bar_chart(parser, token):
return DataForTag.handle_token(parser, token, 'data/charts/barchart.html')
@register.tag
def render_pie_chart(parser, token):
return DataForTag.handle_token(parser, token, 'data/charts/piechart.html')
@register.tag
def render_data_table(parser, token):
return DataForTag.handle_token(parser, token, 'data/table.html')