You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 14:48:16