I have two datasets:
ButikPages = ShopPages.objects.filter(UserID_id=User, Parent_id__isnull=True, IsActive=1, URL=shop_page_slug)
SubPages = ShopPages.objects.filter(UserID_id=User, Parent_id__isnull=False, URL=shop_page_slug)
In my Template I try to filter these two lists that if one ButikPages Query has SubPages it should a drop down menu if not a link menu.
<ul class="navbar-nav">
{% for page in ButikPages %}
{% for parentpage in SubPages %}
{% if page.IsActive == 1 and parentpage.Parent_id != page.ID %}
<li class="nav-item"><a class="nav-link" href="/{{ page.Slug }}/">{{ page.PageTitle }}</a></li>
{% else %}
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown">{{ page.PageTitle }}</a>
{% if parentpage.Parent_id == page.ID and parentpage.IsActive == 1 %}
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="/{{ parentpage.Slug }}/">{{ parentpage.PageTitle }}</a></li>
</ul>
</li>
{% endif %}
{% endif %}
{% endfor %}
{% endfor %}
</ul>
That works if a Menu just has one entry, but if I have two SubPages it appears two time, which is what I understand because the two for loops. But how can I access the SubPages without the second loop?
PS its easier if I just have one menu type I know it's working but the only difference is that I have two kind of menues.
regards.
It seems like you have built a tree-like object list in the model ShopPages
.
I think you should create the tree-like structure in your view first, and then display it in the template later, instead of using two for-loop directly in the template.
Something like:
shop_pages = ShopPages.objects.filter(UserID_id=User, IsActive=1, URL=shop_page_slug)
parents = list(shop_pages.filter(Parent_id__isnull=True).values('pk', 'Parent_id'))
children = list(shop_pages.filter(Parent_id__in=parents).values('pk', 'Parent_id'))
pages = [
{
'pk': parent['pk'],
'parent_id': parent['Parent_id'],
'sub_pages': [
{
'pk': child['pk'],
'parent_id': child['Parent_id'],
} for child in children if child['Parent_id'] == parent['pk']
],
} for parent in parents
]
And in your template, do something like:
{% for page in pages %}
{{ page.pk }}
..
..
{% for sub_page in page.sub_pages %}
{{ sub_page.pk }}
..
..
{% endfor %}
{% endfor}
Sorry I cannot test it now. But I found some mistakes about the position for
loop of children. Maybe it works now.
I just suddenly figure out that you can use the reverse-FK to collect the children of your parent-pages. So if you doesn't change the related_name
of the FK Parent_id
, its reverse field would be Parent_id_set
, then you can do:
shop_pages = ShopPages.objects.filter(UserID_id=User, IsActive=1, URL=shop_page_slug)
and
<ul>
{% for page in shop_pages %}
{{ page.pk }}
..
{% for sub_page in page.Parent_id_set.all %}
{{ sub_page.pk }}
..
{% endfor %}
{% endfor %}
</ul>