0

I'm trying to create a custom StructBlock which I wanna use inside the StreamField. Here in the StructBlock I have 4 fields, namely:

  • background_style
  • title
  • image
  • category

That's my code:

from django.db import models

from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.fields import StreamField

from wagtail.wagtailcore import blocks
from wagtail.wagtailimages.blocks import ImageChooserBlock
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from wagtail.wagtailsnippets.models import register_snippet

from wagtail.wagtailadmin.edit_handlers import FieldPanel, StreamFieldPanel
from modelcluster.fields import ParentalKey

from .vars import BackgroundChoices


class BaseBlock(blocks.StructBlock):
    background_style = blocks.ChoiceBlock(choices=BackgroundChoices, icon='color', required=False)


@register_snippet
class LeadCaptureCategory(models.Model):
    name = models.CharField(max_length=255)
    about = models.CharField(max_length=255, blank=True)
    icon = models.ForeignKey(
        'wagtailimages.Image', null=True, blank=True,
        on_delete=models.SET_NULL, related_name='+'
    )

    panels = [
        FieldPanel('name'),
        FieldPanel('about'),
        ImageChooserPanel('icon'),
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'Lead Capture Categories'


class LeadCaptureForm(BaseBlock):
    title = blocks.CharBlock(required=False)
    image = ImageChooserBlock(required=False)
    category = blocks.BlockField(ParentalKey('LeadCaptureCategory'))

    class Meta:
        icon = 'plus-inverse'
        label = 'lead capture form'.title()
        admin_text = label
        template = 'home/blocks/lead_capture_form.html'


class HomePage(Page):
    template = 'home/home_page.html'
    menu = models.CharField(max_length=128, blank=True)
    body = StreamField([
        ('lead_capture_form', LeadCaptureForm()),
    ], blank=True)

    content_panels = Page.content_panels + [
        StreamFieldPanel('body'),
    ]

3 of these fields in the admin are rendered correctly, except category (which doesn't render at all). You can see that the category is based on the modelcluster.fields.ParentalKey. Could that be the problem?

enter image description here

Any idea how to solve this?

In [27]: wagtail.__version__
Out[27]: '1.13.1'
NarūnasK
  • 4,564
  • 8
  • 50
  • 76

1 Answers1

2

You're right, you can't build a block from a ParentalKey like that. It looks like what you really want is a SnippetChooserBlock:

from wagtail.wagtailsnippets.blocks import SnippetChooserBlock

class LeadCaptureForm(BaseBlock):
    title = blocks.CharBlock(required=False)
    image = ImageChooserBlock(required=False)
    category = SnippetChooserBlock(LeadCaptureCategory)
gasman
  • 23,691
  • 1
  • 38
  • 56