Не сбрасывать цикл на несколько шаблонов рендера () - PullRequest
0 голосов
/ 08 декабря 2010

Я сделал тег, который отображает пользовательский шаблон на основе типа модели. Я нуждался в этом, потому что я хотел показать больше деталей, чем django.views.generic.list_detail.object_list, позвольте мне показать для одного объекта, и у меня есть несколько объектов разных видов. Вот код:

Шаблон тегов / 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)

Моя проблема в том, что шаблон использует {{цикл}} и значения сбрасываются при каждом вызове 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 голосов
/ 08 декабря 2010

Измените свой object_item.html, чтобы он выглядел так:

{% for item in item_list %}
<div class="{{ cycle 'odd' 'even' }}" >
    ...
</div>
{% endfor %}

А затем измените определение render () в вашем RenderItemListNode:

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
0 голосов
/ 08 декабря 2010

Причина, по которой это происходит, заключается в том, что тег цикла работает, когда он находится внутри цикла for - в вашем шаблоне нет цикла for, поэтому цикл не обновляется.

Если вы хотитечтобы использовать цикл таким, какой он есть, вы можете попытаться отобразить весь список объектов в вашем шаблоне, а затем сделать так, чтобы ваш шаблон делал цикл for над ними - вместо того, чтобы делать цикл в вашем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...