Фильтрация по PageQuerySet (которая переустанавливается с помощью specific ()) возвращает FieldError в Wagtail - PullRequest
1 голос
/ 05 апреля 2019

Я использую подклассную модель Wagtail Page. В приведенном ниже коде вы можете видеть, что PhoenixPage является базовой страницей, которая является подклассом модели Wagtail Page.

Подклассы PhoenixArticlePage & PhoenixMealPrepPage Подклассы PhoenixPage

PhoenixArticleIndexPage подклассы PhoenixBaseIndexPage, которые, в свою очередь, подклассы PhoenixPage

Идея состоит в том, чтобы использовать PhoenixArticleIndexPage для всех других страниц статьи.

Проблема даже после использования метода specific () в наборе запросов. Я не могу использовать фильтр или любую другую операцию в наборе запросов. я попытался использовать 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"]

Вот запросы оболочки, которые я пробовал.

Указатель

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 ...***

Но если я перейду к определенной записи в наборе запросов, то смогу увидеть поле тегов на ней.

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>

Может быть, все вместе, но для справки, добавив его сюда.

Найден угловой случай использования разностных () и специфических () методов в наборе запросов.

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 Ответ

3 голосов
/ 05 апреля 2019

Метод specific() в PageQuerySet работает, выполняя первоначальный запрос к базовой модели Page в обычном режиме, а затем выполняет дополнительные запросы - по одному для каждого отдельного типа страницы, найденного в результатах, - для извлечения информации из конкретной страницы.моделей.Это означает, что невозможно использовать поля из конкретной модели в предложениях filter или order_by, потому что они должны быть частью исходного запроса, и в этот момент Django не может узнать, какие модели страниц задействованы.

Однако, если вы знаете, что ваш запрос должен когда-либо возвращать только страницы одного определенного типа (в данном случае PhoenixPage), содержащие поле, по которому вы хотите фильтровать / упорядочивать, вы можете реорганизовать выражение запроса так, чтобывместо этого на этой модели происходит запрос:

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