Search code examples
templatesdjango-templatestagswagtailcode-snippets

Wagtail - having trouble rendering data with related snippets and tags on a page


I have the following code for a wagtail page

from django.db import models
from django import forms
from wagtail.admin.edit_handlers import FieldPanel, InlinePanel, MultiFieldPanel 
from wagtail.core.models import Page, Orderable
from wagtail.images.models import Image
from wagtail.snippets.models import register_snippet
from modelcluster.fields import ParentalManyToManyField


@register_snippet
class GalleryCategory(models.Model):
    name = models.CharField(max_length=255)

    panels = [
        FieldPanel('name'),
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'gallery categories'


class GalleryPage(Page):
    """
    User can add images to the gallery via tags
    """
    categories = ParentalManyToManyField('gallery.GalleryCategory', blank=True)

    class Meta:
        verbose_name_plural = 'Gallery Page'

    content_panels = Page.content_panels + [
        FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
    ]

    def get_context(self, request):
        context = super().get_context(request)
        category_images = {}
        categories = self.categories.all()

        for category in categories:

           tagged_images = Image.objects.filter(

                tagged_items__tag__name='gallery').filter(tagged_items__tag__name=category.name)

        category_images[category.name] = tagged_images
        context['category_images'] = category_images
        return context

I'm having a hard time getting it to render in the template.

I've tried doing it this way

{% block content %}
    <h1>{{ page.title }}</h1>
    {% if category_images %}
        {% for category in category_images %}
            <p> {{ category.name }} </p>
            {% for image in category.images %}
                <p>
                {{ image.title }}
                {% image image fill-320x240 %}
                </p>
            {% endfor %}
    {% endfor %}
{% endif %}

I've tried a few other ways too, by trying to access the nested information with categories.0, image.0, {% for key,value in category %}, {% for key,value in image %}. I'm stuck and if anyone could give me some pointers as to how to access the nested information, I would be very grateful.


Solution

  • Your category_images variable is a dictionary, mapping category names to a list of images, and you can loop over that using category_images.items, which will give you back a sequence of (name, list_of_images) pairs:

    {% for name, images in category_images.items %}
        <p> {{ name }} </p>
        {% for image in images %}
            <p>
                {{ image.title }}
                {% image image fill-320x240 %}
            </p>
        {% endfor %}
    {% endfor %}