I am trying to render StreamField which is located in OrderaBle class And has a ParentalKey.
I can easily access every value from StreamField with for loop in items, but what i want is the following:
I want to loop through the blocks for e.g : {% for block in page.submenu %} (or self.submenu)
But when i am trying to do it i am getting nothing, so it seems i can't access blocks because of ParentalKey i think.
from django.db import models
from django_extensions.db.fields import AutoSlugField
from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel
from wagtail.admin.edit_handlers import (
MultiFieldPanel,
InlinePanel,
FieldPanel,
PageChooserPanel,
StreamFieldPanel
)
from wagtail.core.fields import StreamField
from wagtail.core.models import Orderable
from wagtail.snippets.models import register_snippet
from streams import blocks
from wagtail.core.models import Page
class MenuItem(Orderable):
link_title = models.CharField(blank=True, null=True, max_length=50)
link_url = models.CharField(blank=True, max_length=500,)
link_page = models.ForeignKey("wagtailcore.Page", null=True, blank=True, related_name="+", on_delete=models.CASCADE)
link_target = models.BooleanField(default=False, blank=True)
# thirdmenu = StreamField([
# ("thirdmenu", blocks.MenuBlock())
# ],
# null=True,
# blank=True
# )
page = ParentalKey("Menu", related_name="menu_items")
submenu = StreamField([
("menus", blocks.MenuBlock()),
('thirdmenu', blocks.ThirdMenuBlock())
],
null=True,
blank=True
)
panels = [
FieldPanel("link_title"),
FieldPanel("link_url"),
PageChooserPanel("link_page"),
FieldPanel("link_target"),
StreamFieldPanel("submenu"),
# StreamFieldPanel("thirdmenu")
]
@property
def link(self):
if self.link_page:
return self.link_page.url
elif self.link_url:
return self.link_url
return '#'
@property
def title(self):
if self.link_page and not self.link_title:
return self.link_page.title
elif self.link_title:
return self.link_title
return 'Missing Title'
@register_snippet
class Menu(ClusterableModel):
title = models.CharField(max_length=100)
slug = AutoSlugField(populate_from="title", editable=True)
panels = [
MultiFieldPanel([
FieldPanel("title"),
FieldPanel("slug"),
],
heading="Menu"),
InlinePanel('menu_items', heading="Menu Items"),
]
def __str__(self):
return self.title
{% load wagtailcore_tags %}
{% load static %}
<header>
<div class="navbar-container">
<nav class="navbar navbar-expand-lg navbar-light">
<div class="container">
<a class="navbar-brand" href="/">
<img src="{% static 'assets/logo.svg' %}" loading="lazy" alt="Codely Logo" class="nav-logo-img">
<div class="nav-name">Vetsch<br>Gebäudehüllen</div>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false"
aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="dropdown">
{% for item in menu.menu_items.all %}
<a class="nav-item" href="#" role="button" id="navbarNavDropdown" data-bs-toggle="dropdown" aria-expanded="false" style="color: #333333">
{{ item.title }}
</a>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuLink">
{% for block in page.submenu %}
{{ block.title }}
<ul class="dropdown-menu dropdown-submenu">
{% for b in i.thirdmenu %}
<li>
<a class="dropdown-item" href="{{ b.page }}">{{ b }}</a>
</li>
{% endfor %}
</li>
</ul>
{% endfor %}
</ul>
{% endfor %}
</div>
</header>