2

I have some problems saving an Article page in wagtail, I have 3 classes: ArticlePageModule, ArticlePageModulePlacement and ArticlePage

The error says:

File "/opt/miniconda3/envs/nefodev/lib/python3.7/site-packages/django/db/models/base.py", line 1222, in full_clean
    raise ValidationError(errors)
django.core.exceptions.ValidationError: {'title': ['This field cannot be blank.']}

My intention is to have a section of dynamic articles that you can add using the snippet like this:

  • Page with several articles (preview only).
  • By clicking on the article send to your own article page
  • In the wagtail admin you can manage the articles by publication dates

My code (supported by this code: this)

from django.db import models
from wagtail.core.fields import StreamField
from wagtail.admin.edit_handlers import FieldPanel, StreamFieldPanel, InlinePanel
from wagtail.images.edit_handlers import ImageChooserPanel
from wagtail.core.models import Page, Orderable
from modelcluster.fields import ParentalKey
from wagtail.snippets.models import register_snippet
from wagtail.snippets.edit_handlers import SnippetChooserPanel
from wagtail.images.blocks import ImageChooserBlock
from wagtail.core import blocks
from wagtail.contrib.routable_page.models import RoutablePageMixin, route


# Create your models here.
@register_snippet
class ArticlePageModule(models.Model):

    title = models.CharField(max_length=80)
    subtitle = models.CharField(max_length=50)
    thumbImage =  models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    panels = [
        FieldPanel('title'),
        FieldPanel('subtitle'),
        ImageChooserPanel('thumbImage')
    ]

    def __str__(self):
        return self.title

class ArticlePageModulePlacement(Orderable, models.Model):
    page = ParentalKey('blog.ArticlePage', on_delete=models.CASCADE, related_name='article_module_placements')

    article_module = models.ForeignKey(ArticlePageModule, on_delete=models.CASCADE, related_name='+')

    slug = models.SlugField()

    panels = [
        FieldPanel('slug'),
        SnippetChooserPanel('article_module'),
    ]

class ArticlePage(Page, RoutablePageMixin):

    content = StreamField([
        ('heading', blocks.CharBlock()),
        ('content', blocks.RichTextBlock()),
        ('image', ImageChooserBlock()),
    ])

    content_panels = [
        InlinePanel('article_module_placements', label="Modules"),
        StreamFieldPanel('content')
    ]

    @route(r'^module/(?P<slug>[\w\-]+)/$')
    def page_with_module(self, request, slug=None):
        self.article_module_slug = slug
        return self.serve(request)


    def get_context(self, request):
        context = super().get_context(request)

        if hasattr(self, 'article_module_slug'):
            context['ArticlePageModule'] = self.article_module_placements.filter(slug = self.article_module).first().article_module

        return context
Nefonfo
  • 35
  • 4

1 Answers1

0

You've left out the page title field from content_panels - as the error message says, this is a required field on page models. Normally, you'd pull this in from Page.content_panels:

class ArticlePage(Page, RoutablePageMixin):
    # ...

    content_panels = Page.content_panels + [
        InlinePanel('article_module_placements', label="Modules"),
        StreamFieldPanel('content')
    ]
gasman
  • 23,691
  • 1
  • 38
  • 56