测试 Django Wagtail - 断言可以使用提供的 POST 数据在父级下创建给定页面类型的子级

Testing Django Wagtail - assert that a child of the given Page type can be created under the parent, using the supplied POST data

我已经将自定义页面模型(博客 post)定义为父模型(博客索引页面)的子模型,我想测试该子模型是否可以在其父模型下创建。

BlogPage 和 BlogIndexPage 模型是从文档中的 wagtail“基本博客”示例复制而来的,并且按预期工作。

我正在尝试遵循 documentation 但我收到以下验证错误:

AssertionError: Validation errors found when creating a cms.blogpage:
E             date:
E               This field is required.
E             intro:
E               This field is required.
E             slug:
E               This field is required.
E             title:
E               This field is required.

我怀疑我对夹具的定义不正确,但我不是正确的形式。任何帮助是极大的赞赏!有人可以解释为什么它不起作用吗?

夹具(apps.cms.tests.fixtures.blogPage.json):

[
  {
    "model":"wagtailcore.page",
    "pk": 1,
    "fields":{
      "date":"2022-02-28",
      "intro":"intro to the post...",
      "slug":"slug/",
      "title":"the title",
      "body":"body of the post...",
      "categories":[
        1
      ],
      "content_type": ["cms", "blogpage"],
      "depth": 2
    }
  },
  {
    "model": "cms.blogpage",
    "pk": 1,
    "fields": {}
  }
]

测试class (apps.cms.tests.test_pages.py):

class MyPageTests(WagtailPageTests):
    def setUp(self):
        self.login()
        page = BlogIndexPage(title="Home page", slug="home", path="foo", depth=1)
        page.save()

    def test_create_blog_post(self):
        cwd = Path.cwd()
        root_page = BlogIndexPage.objects.first()
        with open(f"{cwd}/lettergun/apps/cms/tests/fixtures/BlogPage.json") as json_file:
            fixture = json.load(json_file)

        # Assert that a ContentPage can be made here, with this POST data
        self.assertCanCreate(root_page, BlogPage, nested_form_data(fixture))

模特(apps.cms.models.py):

class BlogIndexPage(Page):
    template = "blog.html"
    intro = models.TextField(blank=True)

    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 BlogPageTag(TaggedItemBase):
    content_object = ParentalKey("BlogPage", related_name="tagged_items", on_delete=models.CASCADE)


class BlogPage(Page):
    template = "blog-post.html"

    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="Blog information",
        ),
        FieldPanel("intro"),
        FieldPanel("body"),
        InlinePanel("gallery_images", label="Gallery images"),
    ]

self.assertCanCreate 的最后一个参数是要提交给 'create page' 管理视图的 HTTP POST 数据字典。这与固定装置(它是存储在数据库中的页面数据的表示)完全不同,并且数据结构不兼容。

在最简单的情况下,POST 字典可以只包含必填字段 dateintroslugtitle:

self.assertCanCreate(root_page, BlogPage, {
    'date': '2022-02-28',
    'intro': "intro to the post...",
    'slug': 'my-blog-page',
    'title': 'My blog page',
})

仅当您的测试创建的页面的数据比简单的字段列表更复杂时,才需要 nested_form_data 帮助程序 - 例如,如果您希望页面数据包含一些图库图片,您需要将它与 inline_formset 助手一起使用。 由于您的页面上有一个 InlinePanel,即使您没有传递它,您也需要考虑到这一点数据 - 有关详细信息,请参阅