'Testing Django Wagtail - assert that a child of the given Page type with an image can be created under the parent

I've defined a custom page model (a blog post) as a child of a parent model (a blog index page) and I want to test that the child can be created under its parent.

The BlogPage and BlogIndexPage models are copied from the wagtail "basic blog" example in the documentation, and works as expected.

I'm trying to follow the documentation but I get the following error:

AssertionError: Creating a page failed for an unknown reason

Through trial and error, I know that the error is caused by including an InlinePanel that references another model (BlogPageGalleryImage). If I remove this panel from my BlogPost model definition then the test will pass. I don't understand why including the panel causes an error, or how to solve this problem.

Any help is much appreciated!

The problematic line:

...

InlinePanel("gallery_images", label="Gallery images"),

...

The models:

class BlogIndexPage(Page):
    template = "blog.html"
    intro = models.TextField(blank=True)
    subpage_types = ["cms.BlogPage", "cms.SimpleBlogPage", "cms.BlogTagIndexPage"]

    def get_context(self, request):
        # Update context to include only published posts, ordered by reverse-chron
        context = super().get_context(request)
        blogpages = self.get_children().live().order_by("-first_published_at")
        context["blogpages"] = blogpages
        return context

    content_panels = Page.content_panels + [FieldPanel("intro", classname="full")]


class BlogPage(Page):
    template = "blog-post.html"
    parent_page_types = ["cms.BlogIndexPage"]

    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)
    body = RichTextField(blank=True)
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True)
    categories = ParentalManyToManyField("cms.BlogCategory", blank=True)

    def main_image(self):
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None

    search_fields = Page.search_fields + [
        index.SearchField("intro"),
        index.SearchField("body"),
    ]

    content_panels = Page.content_panels + [
        MultiFieldPanel(
            [
                FieldPanel("date"),
                FieldPanel("tags"),
                FieldPanel("categories", widget=forms.CheckboxSelectMultiple),
            ],
            heading="Meta data",
        ),
        FieldPanel("intro"),
        FieldPanel("body"),
        InlinePanel("gallery_images", label="Gallery images"),
    ]


class BlogPageGalleryImage(Orderable):
    page = ParentalKey(BlogPage, on_delete=models.CASCADE, related_name="gallery_images")
    image = models.ForeignKey("wagtailimages.Image", on_delete=models.CASCADE, related_name="+")
    caption = models.CharField(blank=True, max_length=250)

    panels = [
        ImageChooserPanel("image"),
        FieldPanel("caption"),
    ]

The test:

class MyPageTests(WagtailPageTests):
    def setUp(self):
        self.login()

        indexPage = BlogIndexPage(title="Home page", path="blog", pk=1, depth=1)
        indexPage.save()

        page = BlogPage(
            title="a blog post", intro="an intro", path="blog/post", depth=2, date="2022-02-23"
        )
        page.save()

        image = Image(height=1, width=1)
        image.save()

        galleryImage = BlogPageGalleryImage(pk=1, page=page, image=image, caption="foo")
        galleryImage.save()

        category = BlogCategory(name="cat1", pk=1)
        category.save()

    def test_create_blog_post(self):
        root_page = BlogIndexPage.objects.first()

        data = {
            "date": datetime.date(2022, 2, 28),
            "title": "the title",
            "intro": "the intro",
            "depth": 2,
        }

        self.assertCanCreate(root_page, BlogPage, data)


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source