测试 Django Wagtail - 断言可以在父级下创建具有图像的给定页面类型的子级
Testing Django Wagtail - assert that a child of the given Page type with an image can be created under the parent
我已经将自定义页面模型(博客 post)定义为父模型(博客索引页面)的子模型,我想测试是否可以在其父模型下创建子模型。
BlogPage 和 BlogIndexPage 模型是从 documentation 中的 wagtail“基本博客”示例复制而来的,并且按预期工作。
我正在尝试按照文档进行操作,但出现以下错误:
AssertionError: Creating a page failed for an unknown reason
通过反复试验,我知道错误是由包含引用另一个模型(BlogPageGalleryImage
)的InlinePanel
引起的。如果我从我的 BlogPost 模型定义中删除此面板,那么测试将通过。我不明白为什么包含面板会导致错误,或者如何解决这个问题。
非常感谢任何帮助!
有问题的行:
...
InlinePanel("gallery_images", label="Gallery images"),
...
模特:
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"),
]
测试:
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)
传递给 assertCanCreate
的数据是要由 'create' 视图处理的 HTTP 表单提交数据的字典。当您将 InlinePanel 作为创建表单的一部分时 - 即使您没有向其中传递任何数据 - 也会有 a bundle of extra form fields that needs to be present,告诉它有多少子表单正在提交。
您可以使用 Wagtail 的测试实用程序中的 inline_formset
helper (in conjunction with the nested_form_data
助手将嵌套结构展平为一组普通的表单字段)来构建兼容的表单提交:
from wagtail.tests.utils.form_data import inline_formset, nested_form_data
class MyPageTests(WagtailPageTests):
# ...
def test_create_blog_post(self):
root_page = BlogIndexPage.objects.first()
data = nested_form_data({
"date": datetime.date(2022, 2, 28),
"title": "the title",
"intro": "the intro",
"gallery_images": inline_formset([])
})
self.assertCanCreate(root_page, BlogPage, data)
(您不需要在表单提交中包含 depth
,因为这是一个内部数据库字段,用于跟踪页面在页面树中的位置 - 并且已经在assertCanCreate
调用您指定的 root_page
作为父页面。)
我已经将自定义页面模型(博客 post)定义为父模型(博客索引页面)的子模型,我想测试是否可以在其父模型下创建子模型。
BlogPage 和 BlogIndexPage 模型是从 documentation 中的 wagtail“基本博客”示例复制而来的,并且按预期工作。
我正在尝试按照文档进行操作,但出现以下错误:
AssertionError: Creating a page failed for an unknown reason
通过反复试验,我知道错误是由包含引用另一个模型(BlogPageGalleryImage
)的InlinePanel
引起的。如果我从我的 BlogPost 模型定义中删除此面板,那么测试将通过。我不明白为什么包含面板会导致错误,或者如何解决这个问题。
非常感谢任何帮助!
有问题的行:
...
InlinePanel("gallery_images", label="Gallery images"),
...
模特:
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"),
]
测试:
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)
传递给 assertCanCreate
的数据是要由 'create' 视图处理的 HTTP 表单提交数据的字典。当您将 InlinePanel 作为创建表单的一部分时 - 即使您没有向其中传递任何数据 - 也会有 a bundle of extra form fields that needs to be present,告诉它有多少子表单正在提交。
您可以使用 Wagtail 的测试实用程序中的 inline_formset
helper (in conjunction with the nested_form_data
助手将嵌套结构展平为一组普通的表单字段)来构建兼容的表单提交:
from wagtail.tests.utils.form_data import inline_formset, nested_form_data
class MyPageTests(WagtailPageTests):
# ...
def test_create_blog_post(self):
root_page = BlogIndexPage.objects.first()
data = nested_form_data({
"date": datetime.date(2022, 2, 28),
"title": "the title",
"intro": "the intro",
"gallery_images": inline_formset([])
})
self.assertCanCreate(root_page, BlogPage, data)
(您不需要在表单提交中包含 depth
,因为这是一个内部数据库字段,用于跟踪页面在页面树中的位置 - 并且已经在assertCanCreate
调用您指定的 root_page
作为父页面。)