不重置多个模板渲染周期()

时间:2010-12-07 23:16:07

标签: django django-templates

我制作了一个基于模型类型呈现自定义模板的标记。我需要这个,因为我想显示比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)

2 个答案:

答案 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