Как обернуть функцию поиска в класс, который наследуется от 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