如何以编程方式在 wagtail 中使用流字段创建页面

问题描述 投票:0回答:1

我正在尝试测试 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)
wagtail wagtail-streamfield
1个回答
0
投票

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)
© www.soinside.com 2019 - 2024. All rights reserved.