---
title: "Wagtail 配置中文全文检索"
url: "https://lerry.me/post/2023/04/fulltext-search-with-wagtail-and-postgresql"
date: 2023-04-18T14:00:00.000Z
updated: 2026-08-25T15:09:13.434Z
tags:
  - "Python"
  - "database"
  - "Django"
  - "Wagtail"
  - "fulltext search"
language: zh-CN
---

# Wagtail 配置中文全文检索

Django是我学习的第一个web框架。多年前，家人手术住院，我陪床，闲着无事，我跟着Django教程一步一步实现了一个简单的留言板，并部署到了一个免费的空间。我把链接发给好友，那种喜悦和成就感至今还记得，也让我开始对Python编程产生了浓厚的兴趣。后来用过web.py、Tornado、fastapi等多种框架。但是开始一个新项目时，大多时候Django是我的首选，功能完善，开箱即用。

Wagtail是一个基于Django开发的CMS系统，它不能直接使用，而是需要有经验的Python程序员基于它去开发自己的网站。它提供了优美、丰富、实用的后台管理界面，也基于Django扩展了很多方便开发的模块和功能。有趣的是，我第一次用这个框架时曾经去查询过wagtail这个单词的意思是一种叫“鹡鸰”的小鸟，面对这两个生僻的字，我瞄了一眼就关上了网页。前一阵子在贵州高速的一个服务区看到了一只很特别的小鸟，用识图App查到它就是白鹡鸰，而且挺常见的。但直到最近我用Wagtail开发我自己的博客程序，我才把两者联系到一起，也发现Wagtail log上的那只小鸟很传神。

之前用Tornado开发博客时，几乎是手写的SQL语句来实现包括全文检索在内的查询，简单，纯粹。而使用Wagtail，在通读了官方文档后，只需要很少的代码和很少的配置就可以实现了。Wagtail支持数据库和Elasticsearch作为搜索后端，我的内容不多，托管程序的服务器的内存也有限，就选择了我比较熟悉和喜欢的PostgreSQL作为数据库和搜索后端。

我这里使用的软件包版本如下，版本差异较大的话，api可能会有修改，我以当前使用的版本为例。

```python
Django>=4.1,<4.2
wagtail>=4.2,<4.3
```

### 配置PostgreSQL

因为PostgreSQL默认不支持中文分词，所以需要安装对应的插件。我在[之前博文](https://lerry.me/post/2021/01/python-postgresql-fulltext-search/)中写过如何配置了，此处不再赘述，建议用Docker去运行自己的PostgreSQL实例。

### 配置数据库

需要在你使用的数据库执行几行sql语句，用于创建全文检索的配置文件，如果使用Django的话，可以写在migrations里边，如下，

```python
from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
    ]

    operations = [
        # 导入 SQL 语句
        migrations.RunSQL('''
            CREATE EXTENSION zhparser;
            CREATE TEXT SEARCH CONFIGURATION zh (PARSER = zhparser);
            ALTER TEXT SEARCH CONFIGURATION zh ADD MAPPING FOR n,v,a,i,e,l WITH simple;
        '''),
    ]
```

这里边的“zh”是配置的名称，可以自定义，只要和代码里保持一致即可

### 设置Wagtail程序

首先在项目的配置文件指定使用的配置名称

```python
WAGTAILSEARCH_BACKENDS = {
    "default": {
        "BACKEND": "wagtail.search.backends.database",
        'SEARCH_CONFIG': 'zh',
    }
}
```

这里我们添加了SEARCH_CONFIG这个配置项，如果不进行指定，系统使用的默认配置文件对于中文效果很差。

在 Model 上指定搜索字段：

```python
class BlogEntry(Page): 
    content = MarkdownField(blank=True)
   
    search_fields = Page.search_fields + [
        index.SearchField('content'),
        index.SearchField('title'),
    ]
```

手动更新索引

```bash
./manage.py update_index
```

实际上如果你使用数据库作为搜索后端的话，Wagtail会自动绑定save/delete等信号去更新，因为我要给已有的内容建立索引，所以手动执行了一次更新。

### 如何搜索

当一切配置完毕之后，首先后台的搜索页面可以立刻看到效果。

![Wagtail 搜索后台效果](https://r2.lerry.me/next-blog/uploads/202408/search.png)

其次，也可以在代码中使用搜索功能

```python
q = request.GET.get('q')
BlogEntry.objects.search(q)
```

官方文档中提供了更丰富的功能说明，可以[参考这里](https://docs.wagtail.org/en/stable/topics/search/searching.html)

可以看出，使用Wagtail的搜索系统可以很容易实现全文检索功能，它还有很多功能，我这里只是抛砖引玉，如果你想开发一个博客或者cms，Wagtail是个不错的选择。
