对PageQuerySet的过滤(由specific()重新调整)正在Wagtail中返回FieldError

时间:2019-04-05 02:16:25

标签: wagtail

我正在使用Wagtail Page的子类模型。 在下面的代码中,您可以看到PhoenixPage是基础页面,它继承了Wagtail Page模型。

PhoenixArticlePage和PhoenixMealPrepPage子类是PhoenixPage

PhoenixArticleIndexPage继承了PhoenixBaseIndexPage,而后者又继承了PhoenixPage

想法是将PhoenixArticleIndexPage用于所有其他文章页面。

问题甚至在queryset上使用了specific()方法后,我也无法在queryset上使用过滤器或任何其他操作。 我尝试使用order_by()和filter()

有人可以在这里分享一些见解吗?有什么问题吗?

这是一个模型示例:

class PhoenixPage(Page):
    """
    General use page with caching, templating, and SEO functionality.
    All pages should inherit from this.
    """

    class Meta:
        verbose_name = _("Phoenix Page")

    # Do not allow this page type to be created in wagtail admin
    is_creatable = False
    tags = ClusterTaggableManager(
        through=PhoenixBaseTag,
        verbose_name="Tags",
        blank=True,
        related_name="phoenixpage_tags",
    )

class PhoenixBaseIndexPage(PaginatedListPageMixin, PhoenixPage):
    class meta:
        verbose_name = "Phoenix Base Index Page"
        app_label = "v1"

    index_show_subpages_default = True
    is_creatable = False

class PhoenixArticleIndexPage(PhoenixBaseIndexPage):
    class Meta:
        verbose_name = "Phoenix Article Index Page"
        app_label = "v1"

class PhoenixArticlePage(PhoenixPage):
    class Meta:
        verbose_name = "Phoenix Article Page"
        app_label = "v1"

    subpage_types = []
    parent_page_types = ["v1.PhoenixArticleIndexPage"]

class PhoenixMealPrepPage(PhoenixPage):
    class Meta:
        verbose_name = "Phoenix Meal Prep Page"
        app_label = "v1"
    subpage_types = []
    parent_page_types = ["v1.PhoenixArticleIndexPage"]

这是我尝试过的shell查询。

索引页

In [4]: a  = PhoenixArticleIndexPage.objects.all()[0]
In [5]: a
Out[5]: <PhoenixArticleIndexPage: articles>

按预期,get_children返回Wagtail Page的所有实例。

In [6]: a.get_children()
Out[6]: <PageQuerySet [<Page: article title>, <Page: article title2>, <Page: Our 30-Day Reset Recipes Are So Easy AND Delicious>]>

从“索引”页面获取特定的孩子。

In [7]: a.get_children().specific()
Out[7]: <PageQuerySet [<PhoenixArticlePage: article title>, <PhoenixArticlePage: article title2>, <PhoenixMealPrepPage: Our 30-Day Reset Recipes Are So Easy AND Delicious>]>

获取标签并尝试过滤查询集

In [8]: q = a.get_children().specific()

In [12]: m = PhoenixTag.objects.get(slug='meal')
In [16]: k={"tags":m}
In [19]: q.filter(**k)

***FieldError: Cannot resolve keyword 'tags' into field. Choices are ...***

但是,如果我转到queryset中的特定条目,那么我可以看到其上的标签字段。

In [15]: q[2]
Out[15]: <PhoenixMealPrepPage: Our 30-Day Reset Recipes Are So Easy AND Delicious>

In [16]: q[2].tags
Out[16]: <modelcluster.contrib.taggit._ClusterTaggableManager at 0x1060832b0>

可能是一个不同的问题,但仅供参考,请在此处添加。

找到了在查询集上使用different()和specific()方法的特殊情况。

In [87]: q = PhoenixPage.objects.child_of(a).live()
In [89]: f = q.filter(featured=True)[:3]
In [91]: l = q.difference(f)
In [93]: l.order_by(a.index_order_by).specific() . <-- does not work
DatabaseError: ORDER BY term does not match any column in the result set.

1 个答案:

答案 0 :(得分:3)

PageQuerySet上的specific()方法的工作原理是,像往常一样在基本Page模型上运行初始查询,然后运行其他查询(针对结果中发现的每种不同页面类型进行一次查询)以检索信息从特定的页面模型。这意味着不可能在filterorder_by子句中使用特定模型中的字段,因为这些必须是初始查询的一部分,到那时Django无法知道哪些页面模型参与其中。

但是,如果您知道查询只返回包含要过滤/排序的字段的一种特定类型(在这种情况下为PhoenixPage)的页面,则可以重新组织查询表达式,以便查询发生在该模型上:

PhoenixPage.objects.child_of(a).filter(tags=m).specific()