如何基于Wagtail Page类封装搜索功能并实现模板渲染?
基于Wagtail Page类实现多语言搜索页面的解决方案
一、正确的SearchPage模型实现
from django.db import models from django.shortcuts import render from django.utils.translation import gettext_lazy as _ from wagtail.models import Page from wagtail.fields import RichTextField from wagtail.admin.panels import FieldPanel from wagtail.search.models import Query from wagtail_localize.fields import SynchronizedField, TranslatableField class SearchPage(Page): # 自定义扩展字段,支持多语言翻译 intro = RichTextField(blank=True, verbose_name=_("Introductory Text")) search_placeholder = models.CharField( max_length=100, default=_("Type your search here..."), verbose_name=_("Search Input Placeholder") ) # 后台编辑面板配置 content_panels = Page.content_panels + [ FieldPanel('intro'), FieldPanel('search_placeholder'), ] # wagtail-localize 多语言字段配置 translatable_fields = [ TranslatableField('title'), TranslatableField('intro'), TranslatableField('search_placeholder'), ] # 重写serve方法处理搜索请求逻辑 def serve(self, request): search_query = request.GET.get('query', '') results = [] if search_query: # 记录搜索查询(Wagtail内置统计功能) Query.get(search_query).add_hit() # 执行搜索:可替换为你需要搜索的具体Page子类 results = Page.objects.live().public().search(search_query) # 组装模板上下文 context = self.get_context(request) context.update({ 'search_query': search_query, 'results': results, }) return render(request, self.get_template(request), context) # 指定模板路径(可选,若模板命名与模型匹配可省略) def get_template(self, request, *args, **kwargs): return 'search/search_page.html'
模型关键注意点
- 必须继承
wagtail.models.Page,才能复用Wagtail的页面权限、预览、多语言等核心功能 - 用
gettext_lazy包裹所有需要翻译的字段名和默认值,配合wagtail-localize实现多语言适配 translatable_fields明确标记哪些字段需要翻译,SynchronizedField用于无需翻译、保持同步的字段serve方法替换默认页面逻辑,处理GET参数中的搜索关键词,返回结果上下文
二、模板文件编写
基础布局模板(layout.html)
<!DOCTYPE html> <html lang="{{ request.LANGUAGE_CODE }}"> <head> <meta charset="UTF-8"> <title>{{ page.title }} | My Site</title> {% load static wagtailuserbar %} <link rel="stylesheet" href="{% static 'css/site.css' %}"> </head> <body> {% wagtailuserbar %} <nav> {# 你的导航栏代码 #} </nav> <main> {% block content %}{% endblock %} </main> </body> </html>
搜索页面模板(search/search_page.html)
{% extends "layout.html" %} {% load wagtailcore_tags %} {% block content %} <div class="search-container"> <div class="search-intro"> {{ page.intro|richtext }} </div> <form class="search-form" method="GET" action="{{ page.url }}"> <input type="text" name="query" placeholder="{{ page.search_placeholder }}" value="{{ search_query|default:'' }}" required> <button type="submit">{{ _('Search') }}</button> </form> {% if search_query %} <h3>{{ _('Search Results for "{query}"').format(query=search_query) }}</h3> {% if results %} <ul class="search-results"> {% for result in results %} <li class="result-item"> <h4><a href="{{ result.url }}">{{ result.title }}</a></h4> {% if result.specific.search_description %} <p>{{ result.specific.search_description|truncatewords:20|safe }}</p> {% endif %} </li> {% endfor %} </ul> {% else %} <p class="no-results">{{ _('No matching pages found. Try a different keyword.') }}</p> {% endif %} {% endif %} </div> {% endblock %}
模板关键注意点
- 用
{% extends %}继承基础布局,保证全站样式统一 - 直接通过
page.字段名调用SearchPage的自定义字段,比如page.search_placeholder - 表单提交到当前页面URL(
{{ page.url }}),通过GET参数传递搜索关键词 - 使用
{{ _('翻译文本') }}标记需要多语言转换的静态文本,wagtail-localize会自动提取这些内容
三、常见故障排查
- 模型未显示在Wagtail后台:运行
python manage.py makemigrations和migrate,刷新后台后即可在"Add page"选项中看到SearchPage类型 - 模板渲染报错:检查模板路径是否正确,确保app已添加到Django的
INSTALLED_APPS中,模板文件放在app/templates/目录下 - 多语言不生效:确认
wagtail_localize已添加到INSTALLED_APPS,WAGTAIL_LOCALIZE_ENABLED = True,且在后台创建了对应语言的翻译页面 - 搜索无结果:检查目标Page模型是否配置了
search_fields(比如index.SearchField('body')),搜索时指定具体子类(如BlogPage.objects.live().search(search_query))而非全局Page - serve方法报错:确保导入了
django.shortcuts.render,否则会出现未定义错误
内容的提问来源于stack exchange,提问作者Taneef
相关产品推荐
相关产品推荐

