本文记录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年的最后一天,新的一年希望自己可以继续加油、多学习、多进步!提前来个元旦快乐~!
《django 建站历程系列文章》