我制作了一个基于模型类型呈现自定义模板的标记。我需要这个,因为我想显示比django.views.generic.list_detail.object_list
让我展示单个对象更多的细节,并且我有多个不同种类的对象。这是代码:
templatetags / extra.py:
from django import template
register = template.Library()
def render_item_list(parser, token):
try:
tag_name, item_list = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires exactly one arguments" % token.split_contents()[0]
return RenderItemListNode(item_list)
class RenderItemListNode(template.Node):
def __init__(self, item_list):
self.item_list = template.Variable(item_list)
def render(self, context):
list_html = ''
for item in self.item_list.resolve(context):
context.update({'item':item})
list_html += template.loader.get_template("list/%s_item.html" % item.__class__.__name__.lower()).render(context)
return list_html
register.tag('render_item_list', render_item_list)
我的问题是该模板使用了{{cycle}},并且每次render()
调用都会重置这些值。
我可能会在自己的标记中添加周期值,但我想看看是否有更好的解决方案,比如不在render()
次调用中重置周期值,甚至是不同的方法我的标签。
更多代码:
index.html
:
{% extends "base.html" %}
{% load extra %}
{% block content %}
{% render_item_list item_list %}
{% endblock %}
object_item.html
摘录:
<div class="{{ cycle 'odd' 'even' }}" >
...
</div>
- 编辑: 这是我的新版本的标签,可以在for循环中使用:
def render_item(parser, token):
try:
tag_name, item = token.split_contents()
except ValueError:
raise template.TemplateSyntaxError, "%r tag requires exactly one argument" % token.split_contents()[0]
return RenderItemNode(item)
class RenderItemNode(template.Node):
def __init__(self, item):
self.item = template.Variable(item)
def render(self, context):
item = self.item.resolve(context)
return template.loader.get_template("list/%s_item.html" % item.__class__.__name__.lower()).render(template.Context({'item':item}))
register.tag('render_item', render_item)
答案 0 :(得分:0)
发生这种情况的原因是循环标记在for循环中工作 - 在模板中,没有for循环,因此循环不会更新。
如果要按原样使用循环,可以尝试在模板中渲染整个对象列表,然后让模板对它们进行for循环 - 而不是在代码中执行循环。
答案 1 :(得分:0)
将object_item.html更改为如下所示:
{% for item in item_list %}
<div class="{{ cycle 'odd' 'even' }}" >
...
</div>
{% endfor %}
然后更改RenderItemListNode上的render()定义:
def render(self, context):
item_list = self.item_list.resolve(context)
list_html = template.loader.get_template("list/%s_item.html" % item.__class__.__name__.lower()).render({'item_list':item_list})
return list_html