В чем разница между ChildPage.objects.child_of(self) и ParentPage.get_children()?

#wagtail #django-taggit

#трясогузка #django-taggit

Вопрос:

Я думаю, что ChildPage.objects.child_of(self) и ParentPage.get_children() дают тот же результат, потому subpage_types что ParentPage это только один ['ChildPage'] .

Но когда я пытаюсь отфильтровать результат ParentPage.get_children() , появляется ошибка.

     def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)

        child = self.get_children().live().public()               # <- don't works
        child = ChildPage.objects.child_of(self).live().public()  # <- works

        if request.GET.get('tag', None):
            tags = request.GET.get('tag')
            child = child.filter(tags__slug__in=[tags])  # <- error here

        context["child"] = child
        return context
 

Обратная трассировка (последний последний вызов):

 Cannot resolve keyword 'tags' into field. Choices are: alias_of, alias_of_id, aliases, blogindexpage, blogpage, content_type, content_type_id, depth, draft_title, expire_at, expired, first_published_at, formsubmission, go_live_at, group_permissions, has_unpublished_changes, homepage, id, 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, partnerindexpage, partnerpage, path, redirect, revisions, search_description, seo_title, show_in_menus, sites_rooted_here, slug, title, translation_key, url_path, view_restrictions, workflow_states, workflowpage
 

Ответ №1:

При self.get_children() этом тип страницы дочерних страниц заранее неизвестен — дочерние страницы страницы могут включать несколько разных типов. Поскольку наборы запросов Django (стандартно *) не поддерживают объединение данных из нескольких моделей, результаты возвращаются как базовый Page тип, который содержит только основные поля, общие для всех страниц, такие как заголовок и slug . tags Поэтому фильтрация не выполняется, поскольку это поле не существует в модели страницы.

При ChildPage.objects.child_of(self) этом Django заранее знает, что тип страницы — ChildPage — если self бы у него были дочерние страницы других типов — они не были бы включены в результаты — поэтому он может запрашивать непосредственно в таблице ChildPage, и, следовательно, все поля ChildPage (включая tags ) доступны для фильтрации.

* Wagtail предоставляет specific() метод в наборе запросов для извлечения полных данных страниц, но это реализуется как этап постобработки после выполнения основного запроса к базе данных, так что это все равно не позволит вам filter использовать поля, которые не являются частью базовой модели страницы.