我正在尝试测试 wagtail 中的页面。像下面这样创建页面适用于没有流场的页面。
blogPage = BlogPage(title="Test Blog",path="test-blog", excerpt=rich_text("<p>This is an excerpt </p>"), body=[{"id": "07a1f0b6-0023-45a3-83a0-38cb6a7893f1", "type": "heading", "value": "test heading"}])
root_page = Page.objects.get(id=2)
root_page.add_child(instance=blogPage)
root_page.save()
但是当我尝试创建带有流场(主体)的页面时,当我运行测试assertPageIsPreviewable和assertPageIsEditable时,我收到错误
AssertionError: Failed to load preview for BlogPage "Test Blog" with mode="": 'body-count'
。
我找不到任何文档解释如何使用流场块以编程方式在 wagtail 中创建新页面。不过,我找到了一些解释如何使用的文档
nested_form_data({'data': streamfield([('heading', 'test heading'),])})
但是设置
blogPage = BlogPage(title="Test Blog",path="test-blog", excerpt=rich_text("<p>This is an excerpt </p>"), body=nested_form_data({'body': streamfield([('heading', 'test heading'),])}))
不起作用并将其设置为
blogPage = BlogPage(title="Test Blog",path="test-blog", excerpt=rich_text("<p>This is an excerpt </p>"), body=streamfield([('heading', 'test heading'),]))
也不起作用。我终于能够在 wagtail 最新文档中找到如何执行此操作的文档https://docs.wagtail.org/en/latest/advanced_topics/testing.html#working-with-page-content所以我尝试了:
blogPage = BlogPage(title="Test Blog",path="test-blog", excerpt=rich_text("<p>This is an excerpt </p>"))
blogPage.body.extend([('heading', "test heading")])
blogPage.save()
root_page = Page.objects.get(id=2)
root_page.add_child(instance=blogPage)
root_page.save()
和
blogPage = BlogPage(title="Test Blog",path="test-blog", excerpt=rich_text("<p>This is an excerpt </p>"))
root_page = Page.objects.get(id=2)
root_page.add_child(instance=blogPage)
root_page.save()
blogPage.body.extend([('heading', "test heading")])
blogPage.save()
这些都不起作用。使用 Streamfield 在 wagtail 中创建页面进行测试的正确方法是什么。我不想使用固定装置。 我在 stackoverflow 上发现了这个问题并尝试了这个解决方案,但它也不起作用。
class BlogTestCase(WagtailPageTestCase):
@classmethod
def setUpTestData(cls):
cls.blogPage = BlogPage(title="Test Blog",path="test-blog", excerpt=rich_text("<p>This is an excerpt </p>"))
cls.blogPage.body.extend([('heading', "test heading")])
cls.blogPage.save()
root_page = Page.objects.get(id=2)
root_page.add_child(instance=cls.blogPage)
root_page.save()
def test_is_previewable(self):
self.assertPageIsPreviewable(self.blogPage)
def test_is_editable(self):
self.assertPageIsEditable(self.blogPage)
assertPageIsPreviewable
和 assertPageIsEditable
的工作原理是向编辑页面视图发出 POST 请求,并检查它是否返回非错误响应。这些方法为您提供了提供 POST 请求正文的选项 - 如果省略此选项,它将尝试通过发出 GET 请求(返回编辑表单)并从 HTML 中提取表单数据来获取合适的 POST 正文。但是,如果表单包含 StreamField,则此方法将不起作用,因为 StreamField 的编辑界面是通过 Javascript 生成的,并且不是服务器呈现的 HTML 的一部分。因此,省略 POST 数据的快捷方式不可用。
nested_form_data
中提供的 rich_text
、streamfield
、inline_formset
和 wagtail.test.utils.form_data
帮助器专门用于以所需格式构建 POST 正文 - 在直接使用 BlogPage 对象时不应使用它们,这意味着
blogPage = BlogPage(body=nested_form_data(...))
无效。传递
excerpt=rich_text("...")
也是无效的,尽管这可能是良性的 - 它只是意味着您的 excerpt
将被设置为 JSON 文本字符串,而不是类似 HTML 的内容。 excerpt="<p>This is an excerpt</p>"
在这里是正确的。
代码的最终版本(将(块类型、值)元组列表传递给
body.extend
)是在页面对象上构建 StreamField 内容的正确方法。 (请注意,在使用 blogPage.save()
将其添加到页面树之前,您无法调用 root_page.add_child(instance=blogPage)
,事实上 add_child
也会具有保存 blogPage
的效果,因此您无需两者都做。)
但是,考虑到上述
assertPageIsPreviewable
和 assertPageIsEditable
的限制,无论如何,您最终都必须以 POST 提交的格式提供此数据,这将覆盖您预先在博客页面对象,所以这是一个有争议的问题。
使用
wagtail.test.utils.form_data
中的 POST 数据助手,您的最终代码应为(未经测试):
class BlogTestCase(WagtailPageTestCase):
@classmethod
def setUpTestData(cls):
cls.blogPage = BlogPage(title="Test Blog", slug="test-blog", excerpt="<p>This is an excerpt</p>")
root_page = Page.objects.get(id=2)
root_page.add_child(instance=cls.blogPage)
root_page.save()
cls.post_data = nested_form_data({
"title": "Test blog",
"slug": "test blog",
"excerpt": rich_text("<p>This is an excerpt</p>"),
"body": streamfield([
('heading', "test heading"),
]),
})
def test_is_previewable(self):
self.assertPageIsPreviewable(self.blogPage, post_data=self.post_data)
def test_is_editable(self):
self.assertPageIsEditable(self.blogPage, post_data=self.post_data)