本文记录django最常用的搜索方法,基于django-haystack框架、whoosh引擎、jieba分词的搜索模块实现。
1、安装所需组件:
root@jerryls-site1:/home# pip install whoosh #全文搜索引擎
root@jerryls-site1:/home# pip install django-haystack #搜索框架
root@jerryls-site1:/home# pip install jieba  # 中文分词组件
2、添加APP,配置全局settings.py
# Application definition
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # for allauth
    'django.contrib.sites',
    'allauth',
    'allauth.account',
    'allauth.socialaccount',
    'allauth.socialaccount.providers.baidu',
    # for crispy
    'crispy_forms',
    # for blog
    'blog',
    # for myauth
    'myauth',
    # for image
    'imagekit',
    # for ckeditor
    'ckeditor',
    'ckeditor_uploader',
    # for comment
    'comment',
    # for haytack
    'haystack',
]
HAYSTACK_CONNECTIONS = {
    'default':{
        # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'ENGINE':'blog.whoosh_cn_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    },
}
# 实时自动更新索引配置
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
这里blog下面还没有“whoosh_cn_backend”这个文件,需要下面步骤进行添加:
拷贝“whoosh_backend.py”(/usr/local/lib/python3.5/dist-packages/haystack/backends/whoosh_backend.py)文件到blog下,并重命名为whoosh_cn_backend.py,
修改代码如下:
from jieba.analyse import ChineseAnalyzer   #手动添加结巴分词
# 找到下面这句,大约在160行左右,修改如下:
# schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True) 
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)
3、创建索引文件
我们对文章这个model进行搜索,进入到blog文件夹创建索引:需要创建一个名字固定为“search_indexes.py”的文件,修改代码如下:
# -*- coding: utf-8 -*-
from haystack import indexes
from .models import Article
class ArticleIndex(indexes.SearchIndex, indexes.Indexable): # 名字必须是model名+Index
    text = indexes.CharField(document=True, use_template=True)
    def get_model(self):
        return Article
    def index_queryset(self, using=None):
        return self.get_model().objects.all()
在全局模板文件夹下创建templates/search/indexes/blog文件夹及article_text.txt文件,注意这里的article_text.txt文件名字是“model名_text.txt”,用别的名字会报错。同时创建一个搜索模板文件search.html显示结果用:
root@jerryls-site1:/home/mysite/templates# tree
├── account
│   
.....
.....
├── search
│      └── indexes
│             └── blog
│                   └── article_text.txt
└── search.html
# article_text.txt
{{ object.title }}
{{ object.summary }}
{{ object.body }}
这里指定了对文章的title、summary、body进行搜索。
以下为search.html文件代码:其中{{query}}就是输入的关键字,“{% for result in page.object_list %}”可以遍历结果列表,result.object 即 article。“highlight”对结果进行高亮显示
{% extends "blog/base.html" %}
{% load highlight %}
{% block base_content %}
<style>
span.highlighted { color: red; }
.col-center-block {
        float: none;
        display: block;
        margin: 0 auto;
        /* margin-left: auto; margin-right: auto; */
}
</style>
<div class="container">
    <div class="row">
        <div class="text-center">
          <div class="list-group col-lg-8 col-center-block">
             <a class="list-group-item disabled">当前搜索:{{ query }}</a>
{% for result in page.object_list %}
             <div class="list-group-item">
                <a href="{% url 'blog:article_url' result.object.slug %}">{{result.object.title}}</a>
                <br>
{% with result.object.body|safe as body %}
                <span>{% highlight body with query %}</span>
{% endwith %}
             </div>
{% empty %}
             <h3>未搜索到相关内容!</h3>
{% endfor %}
         </div>
    </div>
</div>
{% endblock %}
4、配置搜索路由
在blog中添加搜索路由:
urlpatterns = [
    path('', index_view, name='index_url'),
    path('article/<str:slug>', article_view, name='article_url'),
    path('cata/<str:slug>', catalogue_view, name='cata_url'),
    path('search/', include('haystack.urls')),    # 搜索路由
]
5、修改导航栏、搜索模板文件
修改nav.html文件,将搜索路由添加到搜索按钮:
<form class="navbar-form navbar-left" method="get" action="{% url 'blog:haystack_search' %}">
   <div class="form-group">
      <input type="text" class="form-control" name="q" placeholder="搜索" required=True>
   </div>
      <button type="submit" class="btn btn-default">搜索</button>
</form>
需要注意的是,这里的搜索输入框一定要指定个name,内容是“q”,这样才能获得正确的路径给haystack,才能搜索到结果。
6、建立索引
最后一步,输入以下命令建立索引即可:
root@jerryls-site1:/home/mysite# ./manage.py rebuild_index
最终的实现效果如下:

天气太冷了,空调死命吹也不好使,躺在被窝也冻得不行。今天是2018年的最后一天,新的一年希望自己可以继续加油、多学习、多进步!提前来个元旦快乐~!
        
        