Данные в формате zipped отображаются в режиме просмотра, но не в templete

row1 = [] row2 = []

categories= Kategoriler.objects.all().filter(parent_id__isnull=True).order_by('id')
for x in categories:
    row1.append(x.title)
    row2.append(Kategoriler.objects.all().filter(parent_id=x.id).order_by('title'))

zipped = itertools.zip_longest(row1, row2)


for u, y in zipped:
    print(">>>>>>>>>>>>>>>", u, "<<<<<<<<<<<<<<<<<<<<")
    for q in y:
        print(q.title)


context = {'segment': 'categories', "zipped": zipped}

Вышеприведенный код печатается, как ожидалось, в файле view.py

In templete;

{{ zipped|length }}
                {%  for u, y in zipped %}
                    {{ u }}---{{ y.title }}
                {%  endfor %}

len дает 0, и цикл пуст. В чем причина этого?

Вы должны неперечислять zip в представлении, поскольку это "съест" итератор, и тогда итератор будет "исчерпан". Вы передаете zipped в представление без перечисления, так:

from itertools import zip_longest

row1 = []
row2 = []
categories = Kategoriler.objects.filter(parent=None).order_by('id')
for x in categories:
    row1.append(x.title)
    row2.append(Kategoriler.objects.filter(parent_id=x.id).order_by('title')

zipped = zip_longest(row1, row2)
# no enumeration
context = {'segment': 'categories', "zipped": zipped}

В шаблоне вы можете затем выполнить рендеринг с помощью:

{% for u, ys in zipped %}
    {% for y in ys %}
        {{ u }}---{{ y.title }}
    {% endfor %}
{% endfor %}

Вам следует неиспользовать {{ zipped|length }}, так как это вновьрасходует молнию.

При этом, молния ненужна и неэффективна: она сделает N+1 запросов, если categories содержит N элементов. Вы можете получить элементы с помощью:

from django.db.models import Prefetch

categories = Kategoriler.objects.filter(
    parent=None
).prefetch_related(
    Prefetch('kategoriler_set', Kategoriler.objects.order_by('title'))
).order_by('id')
context = {'segment': categories}

В шаблоне вы можете отобразить это следующим образом:

{% for segment in segment %}
    {% for sub in segment.kategoriler_set.all %}
        {{ segment.title }}---{{ sub.title }}
    {% endfor %}
{% endfor %}

Если вы установили related_name=… [Django-doc] для ForeignKey с именем parent, то вам следует заменить kategoriler_set на это значение.

Вернуться на верх