如何修复 wagtail 中 rooutablepage 产生的 FieldError

How to fix the FieldError produced by routablepage in wagtail

我有以下 models.py 设置,

class PostList(RoutablePageMixin, Page):
    template = "Post_List.html"
    intro = RichTextField(blank=True)
    content_panels = Page.content_panels + [
        FieldPanel("intro")
        ]

    subpage_types = [
        "PostDetail",
    ]

    parent_page_type = [
        "HomePage",
    ]

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['posts'] = self.posts    
        context['post_list'] = self
        return context

    def get_posts(self):
        return PostList.objects.descendant_of(self).live()


    @route(r'^tag/(?P<tag>[-\w]+)/$')
    def post_by_tag(self, request, tag, *args, **kwargs):
        self.search_type = 'tag'
        self.search_term = tag
        self.posts = self.get_posts().filter(tag__slug=tag)
        return Page.serve(self, request, *args, **kwargs)

    @route(r'^category/(?P<category>[-\w]+)/$')
    def post_by_category(self, request, category, *args, **kwargs):
        self.search_type = 'category'
        self.search_term = category
        self.posts = self.get_posts().filter(category__slug=category)
        return Page.serve(self, request, *args, **kwargs)

    @route(r'^$')
    def post_list(self, request, *args, **kwargs):
        self.posts = self.get_posts()
        return Page.serve(self, request, *args, **kwargs)


class PostDetail(Page):
    template = "Post_Detail.html"
    
    body = RichTextField(blank=True)
    
    tags = ClusterTaggableManager(through="Link_PostDetail_Tag", blank=True)

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

    content_panels = Page.content_panels + [
        FieldPanel("body", classname='full'),
        InlinePanel("rncategory", label="label_category"),     # 'label' determines Title & Button name in Wagtail Admin Portal
        FieldPanel("tags"),
    ]

    parent_page_type = [
        "PostList",
    ]

    subpage_types = []      # Disable "Add CHILD PAGE"

    @property
    def post_list(self):
        return self.get_parent().specific

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context['post_list'] = self.post_list
        context['post_detail'] = self
        return context

@register_snippet
class Category(models.Model):
    name = models.CharField(max_length=255)
    slug = models.SlugField(unique=True, max_length=100)

    panels = [
        FieldPanel("name"),
        FieldPanel("slug"),
    ]

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"


@register_snippet
class Tag(TaggitTag):
    class Meta:
        proxy = True


class Link_PostDetail_Category(models.Model):
    page = ParentalKey(
        "PostDetail", on_delete = models.CASCADE, related_name="rncategory"
    )

    category = models.ForeignKey(
        "Category", on_delete = models.CASCADE, related_name="rnpostdetail"
    )

    panels = [
        SnippetChooserPanel("category"),
    ]

    class Meta:
        unique_together = ("page", "category")


class Link_PostDetail_Tag(TaggedItemBase):
    content_object = ParentalKey("PostDetail", related_name="rntags", on_delete=models.CASCADE)

我在导航到 routablepageurl (/category/events/) 时遇到了以下错误,尽管我已经有一个中介模型 Link_PostDetail_CategoryPostDetail 链接到 Category

FieldError at /info/post-list/category/events/

Cannot resolve keyword 'category' into field. Choices are: alias_of, alias_of_id, aliases, comments, content_type, content_type_id, depth, draft_title, expire_at, expired, first_published_at, formsubmission, go_live_at, group_permissions, has_unpublished_changes, id, intro, last_published_at, latest_revision_created_at, live, live_revision, live_revision_id, locale, locale_id, locked, locked_at, locked_by, locked_by_id, numchild, owner, owner_id, page_ptr, page_ptr_id, path, redirect, revisions, search_description, seo_title, show_in_menus, sites_rooted_here, slug, subscribers, title, translation_key, url_path, view_restrictions, workflow_states, workflowpage

根据下面的 PDB 输出,

[27] > /usr/src/app/IoTSite/models.py(78)post_by_category()
-> self.search_term = category
(Pdb++) pp locals()
{'args': (), 'category': 'events', 'kwargs': {}, 'request': <WSGIRequest: GET '/info/post-list/category/events/'>, 'self': <PostList: Post List>}
(Pdb++) pp self.get_children()[1].specific
<PostDetail: Detail 2>

(Pdb++) pp self.get_children()[1].specific.rncategory.all()
<QuerySet [<Link_PostDetail_Category: Link_PostDetail_Category object (2)>]>
(Pdb++) pp self.get_children()[1].specific.rncategory.all()[0]
<Link_PostDetail_Category: Link_PostDetail_Category object (2)>
(Pdb++) pp self.get_children()[1].specific.rncategory.all()[0].category
<Category: events>
(Pdb++) pp self.get_children()[1].specific.rncategory.all()[0].category.name
'events'
(Pdb++) 

问:我应该如何修改我的源代码来修复错误?

方法:

def get_posts(self):
    return PostList.objects.descendant_of(self).live()

为您提供作为当前页面后代的 PostList 对象的列表。这可能是一个错误 - 您需要一个 PostDetail 对象列表,因为那是定义 category 关系的地方。

def get_posts(self):
    return PostDetail.objects.descendant_of(self).live()