Как обернуть функцию поиска в класс, который наследуется от wagtail Page?

Есть ли способ сделать форму поиска, используя шаблон wagtail, наследующий от Page? Вместо того, чтобы использовать простой view.

И как я могу отобразить его в шаблоне?

Я нахожу более полезной возможность использовать атрибуты страницы wagtail для улучшения стиля страницы поиска, добавления дополнительных полей и перевода на несколько языков, например, с помощью wagtail localyze.

class SearchPage(Page):
    # Database fields
    heading = models.CharField(default="Search", max_length=60)
    intro = models.CharField(default="Search Page", max_length=275)
    placeholder = models.CharField(default="Enter your search", max_length=100)
    results_text = models.CharField(default="Search results for", max_length=100)
    cover_image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    # Editor panels configuration
    content_panels = Page.content_panels + [
        FieldPanel('cover_image'),
        FieldPanel('heading'),
        FieldPanel('intro'),
        FieldPanel('placeholder'),
        FieldPanel('results_text'),
    ]

    def search(self, request):
        search_query = request.GET.get("query", None)
        page = request.GET.get("page", 1)
        active_lang = Locale.get_active()
        # Search
        if search_query:
            search_results = Page.objects.filter(locale_id=active_lang.id, live=True).search(search_query)
            # To log this query for use with the "Promoted search results" module:
            # query = Query.get(search_query)
            # query.add_hit()
        else:
            search_results = Page.objects.none()
        # Pagination
        paginator = Paginator(search_results, 10)
        try:
            search_results = paginator.page(page)
        except PageNotAnInteger:
            search_results = paginator.page(1)
        except EmptyPage:
            search_results = paginator.page(paginator.num_pages)

        return TemplateResponse(
            request,
            "search/search_page.html",
            {
                "search_query": search_query,
                "search_results": search_results,
            },
        )

Мой layout.html файл:

Я попробовал код cissus, но он не работает.

Может ли кто-нибудь помочь мне?

В Wagtail процесс, эквивалентный функции представления Django, происходит в методе с именем serve. Вы можете пройти большую часть пути, переименовав свой метод search в serve.

(При написании представлений Django вы можете назвать функцию как угодно, потому что вы подключаете ее к URL в urls.py - но в Wagtail такого механизма нет, поэтому вам нужно использовать распознанное имя serve. Метод с именем search не будет вызван.)

Далее необходимо убедиться, что соответствующие переменные доступны в вашем шаблоне. В коде вашего шаблона вы используете {{ self.title }} и {{ page.heading }}, но self и page на самом деле ссылаются на один и тот же объект - объект Page, который в данный момент обрабатывает ответ. Я бы рекомендовал стандартизировать page в качестве имени переменной в вашем шаблоне - {{ page.title }}, {{ page.heading }} и так далее.

<<<Поскольку вы переопределяете стандартный механизм обслуживания страниц Wagtail, который обычно заботится о передаче page в шаблон, вам нужно добавить это обратно в вызов TemplateResponse:

    return TemplateResponse(
        request,
        "search/search_page.html",
        {
            "page": self,
            "search_query": search_query,
            "search_results": search_results,
        },
    )

Теперь будут доступны обычные свойства страницы, такие как {{ page.title }}. Однако search_query и search_results здесь являются не свойствами объекта страницы - это просто дополнительные переменные, которые вы передаете шаблону вместе с page - поэтому строки типа {% if page.search_results %} должны быть {% if search_results %} вместо них.

На самом деле, более аккуратным способом добиться того же самого было бы переопределить метод get_context вместо этого. Вам не нужно полностью заменять стандартный механизм обслуживания Wagtail, вплоть до рендеринга ответа шаблона - все, что вы делаете здесь, это вставляете переменные search_query и search_results в то, что уже делает Wagtail. Это будет выглядеть так:

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

    # ... include your existing search logic here, not including the
    # 'return TemplateResponse' part ...

    # Add extra variables and return the updated context
    context['search_query'] = search_query
    context['search_results'] = search_results
    return context
Вернуться на верх