Найти - Пользователи
Полная версия: Jinja2 - цикл for и его разновидность recursive
Начало » Python для новичков » Jinja2 - цикл for и его разновидность recursive
1
AlexStarov
Есть такая модель:
class Category(models.Model):
    parent = models.ForeignKey(u'Category',
                               related_name='children',
                               verbose_name=u'Вышестоящая категория',
                               null=True,
                               blank=True, )
    is_active = models.BooleanField(verbose_name=_(u'Показывать'),
                                    default=True,
                                    blank=False,
                                    null=False, )
    disclose_product = models.BooleanField(verbose_name=_(u'Открывать страницу товара'),
                                           default=True,
                                           blank=False,
                                           null=False,)
    title = models.CharField(verbose_name=u'Заголовок категории',
                             max_length=255,
                             null=False,
                             blank=False, )
    name = models.CharField(verbose_name=u'Наименование категории',
                            max_length=255,
                            null=True,
                            blank=True, )
    description = models.TextField(verbose_name=u'Описание категории',

Есть шаблон на jinja2

    <ul id='accordion' class="menu">
        {%- for cat in all_categories_ recursive %}
            <li>
                <a href="{{ cat.get_absolute_url() }}"
                   alt='{{ cat.name }}'
                   title="{{ cat.title }}">{{ cat.title }}</a>
                {%- if cat.children -%}
                    <ul class="submenu">{{ loop(cat.children) }}</ul>
                {%- endif %}</li>
        {%- endfor %}
    </ul>

во вьюхе я делаю выборку из модели Category
all_categories_ = Category.objects.all()

Теперь вопрос:

Как только в all_categories_ попадают записи с заполненным полем parent начинает срабатывать {% if cat.children %} и естественно вываливаться ошибка ‘RelatedManager’ object is not iterable
Как побороть данную проблему?

UPD:
В результате хотелось бы получить многоуровневое меню, с “практически не ограниченным” количеством вложений.
plusplus
Не до конца я вник в задачу, но может быть мой код поможет, вроде похожее делал:
<ul id='mixed'>
	{# 
		В общем, средств для организации рекурсивного макроса в jinja2 я не нашел,
		поэтому пришлось делать рекурсию с помощью цикла. То есть
		{% for parent in (0,) recursive %} это "def func():", а
		{{ loop((0,)) }} - это func().
	#}
	{% if parents %}
		{% for parent in (0,) recursive %}
			<li class="open"><div class="hitarea"></div>{{ show_equipment(parents.pop()) }}				
			{% if parents %}
				<ul>{{ loop((0,)) }}</ul>
			{% else %}
				<ul>{% include "/equipment/_down_tree.html" %}</ul>
			{%- endif %}</li>
		{% endfor %}
	{% else %}
		{% include "/equipment/_down_tree.html" %}
	{% endif %}
</ul>
AlexStarov
plusplus
Не до конца я вник в задачу, но может быть мой код поможет, вроде похожее делал:

Делал всё по примеру из документации по jinja2. Так что возможно очень напрямую подошол к вопросу - как в примере.

<ul class="sitemap">
{%- for item in sitemap recursive %}
    <li><a href="{{ item.href|e }}">{{ item.title }}</a>
    {%- if item.children -%}
        <ul class="submenu">{{ loop(item.children) }}</ul>
    {%- endif %}</li>
{%- endfor %}
</ul>
bismigalis
Тут дело не в цикле, а в том что RelatedManager не итерабелен.

Что означают черточки после процента?
FishHook
>>>Что означают черточки после процента?
ЕМНИП, они убирают лишние пробелы в теге.
AlexStarov
bismigalis
Тут дело не в цикле, а в том что RelatedManager не итерабелен.

Да именно в этом дело.

Я уже подумал, может во вьюхе нужно формировать словарь с рекурсией?
Чтобы потом в for'е его распаковывать?
bismigalis
AlexStarov
Я уже подумал, может во вьюхе нужно формировать словарь с рекурсией?
Чтобы потом в for'е его распаковывать?

да нет, я думаю надо после children добавить .all()
AlexStarov
bismigalis
да нет, я думаю надо после children добавить .all()

Вы оказались абсолютно правы.

Это я ступил, нарывался же на такое.

В результате шаблон получился такой:
    <ul id='accordion' class="menu basement">
        {%- for cat in categories_basement_ recursive %}
            <li>
                <a href="{{ cat.get_absolute_url() }}"
                   alt='{{ cat.name }}'
                   title="{{ cat.title }}">{{ cat.title }}</a>
                {% set children = cat.children.all() %}
                {%- if children -%}
                    <ul class="submenu sub_level">{{ loop(children) }}</ul>
                {%- endif %}</li>
        {%- endfor %}
    </ul>

при этом во вьюхе я выбираю не весь список категорий а только категории первого уровня:
    from apps.product.models import Category
    try:
        categories_basement_ = Category.manager.basement()
    except Category.DoesNotExist:
        categories_basement_ = None

managers.py
class Manager(models.Manager):
    def basement(self):
        return self.filter(parent__isnull=True, )
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB