安装django-haystack、whoosh、jieba库
pip install django-haystack==2.7.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
pip install whoosh
pip install jieba
’
settings.py中注册应用haystack:
INSTALLED_APPS = [
。。。
'haystack',
]
’
settings.py中添加配置:
# 全文检索框架
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
# 自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
‘
article/search_indexes.py文件内容如下:(文件名字固定!内容供参考,根据具体情况修改,只需修改三处的Article即可)
from .models import Article
from haystack import indexes
class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
# 类名必须为需要检索的Model_name+Index,这里需要检索Article,所以创建ArticleIndex
# use_template根据哪些字段建立索引,将说明放入一个文件中
text = indexes.CharField(document=True, use_template=True) # 创建一个text字段
def get_model(self): # 重载get_model方法,必须要有!
return Article
# 建立索引的数据
def index_queryset(self, using=None):
return self.get_model().objects.all()
templates文件夹下 创建 search/indexes/应用名文件夹/模型类名_text.txt
article_text.txt文件内容设置如下(具体根据模型内容改变):
{{ object.title }}
{{ object.desc }}
{{ object.content }}
’
即根据设置索引值,预先读取出数据库内容,单独放置,以供引擎搜索。
①、打开一个Terminal窗口,在项目路径下执行:
D:Afile/bfile/XxxProjects> python manage.py rebuild_index
②、输入 y 确认创建。
‘
urls.py主路由列表中添加:
url(r’^search/’, include(‘haystack.urls’)),
D:Afile/bfile/XxxProjects> python manage.py runserver
http://127.0.0.1:8000/search/?q=sxxs
在search文件夹下创建search.html文件(固定名字,不可变)
search.html 文件内容如下(参考):
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Titletitle>
head>
<body>
搜索:{{ query }}<br>
page:{{ page }}<br>
{% for item in page %}
{{ item.object.id }} 《 {{ item.object.title }} 》 - {{ item.object.desc }} <br>
{% endfor %}
count:{{ paginator.count }}
body>
html>
浏览器输入: (查询不同内容修改 ?q=不同内容)
http://127.0.0.1:8000/search/?q=内容
此时,多次测试发现:搜索结果不尽如人意,只有输入完整的原文才能查询出结果,输入词语进行模糊查询 基本没用返回结果。
’
whoosh搜索引擎自带的中文分词功能效果较差
为whoosh搜索引擎配置jieba库进行分词。
‘
找到本项目使用的site-packages文件夹
鼠标悬停即可看到包的安装路径:
进入 Lib\site-packages\haystack\backends
在backends文件夹中添加ChineseAnalyzer.py文件(新建txt文件,之后改后缀):
ChineseAnalyzer.py内容如下:(文件保存关闭,但文件夹界面别急着关)
import jieba
from whoosh.analysis import Tokenizer, Token
class ChineseTokenizer(Tokenizer):
def __call__(self, value, positions=False, chars=False,
keeporiginal=False, removestops=True,
start_pos=0, start_char=0, mode='', **kwargs):
t = Token(positions, chars, removestops=removestops, mode=mode,
**kwargs)
seglist = jieba.cut(value, cut_all=True)
for w in seglist:
t.original = t.text = w
t.boost = 1.0
if positions:
t.pos = start_pos + value.find(w)
if chars:
t.startchar = start_char + value.find(w)
t.endchar = start_char + value.find(w) + len(w)
yield t
def ChineseAnalyzer():
return ChineseTokenizer()
’
1、复制whoosh_bcakend.py文件
2、原地粘贴whoosh_bcakend.py文件,改名为whoosh_cn_backend.py
3、修改whoosh_cn_backend.py内容
#导入添加的ChineseAnalyzer文件
from .ChineseAnalyzer import ChineseAnalyzer
xxx
xxx
xxx
#164行左右修改
TEXT(…,analyzer=ChineseAnalyzer(),…)
将原来引用的whoosh_backend,修改为新配置的whoosh_cn_backend:
# 全文检索框架
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
# 自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
Terminal窗口再次执行:
D:Afile/bfile/XxxProjects> python manage.py rebuild_index
另一个Terminal窗口执行启动django服务:
D:Afile/bfile/XxxProjects> python manage.py runserver
可以通过ajax渲染的方式使数据的展示更加灵活。
在应用下的views.py文件中创建:
def searchJson(request):
from haystack.query import SearchQuerySet, Raw
qParams = request.GET.get('q')
if not qParams:
return JsonResponse({
'code': 400,
'msg': '缺少参数'
})
articles = SearchQuerySet().filter(text=Raw(qParams)).order_by('view_num') # 根据浏览量排序显示
res_list = []
try:
for article in articles:
ar_data = {}
ar_data['id'] = article.object.id
ar_data['title'] = article.object.title
res_list.append(ar_data)
except:
pass
return JsonResponse({
'code': 200,
'data': res_list
},json_dumps_params={'ensure_ascii': False})
在应用里的search_indexes.py文件中改写添加view_num:
class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
# 类名必须为需要检索的Model_name+Index,这里需要检索Article,所以创建ArticleIndex
# use_template根据哪些字段建立索引,将说明放入一个文件中
text = indexes.CharField(document=True, use_template=True) # 创建一个text字段
view_num = indexes.CharField(model_attr='view_num') # 变量名自定义且和视图函数保持一致
def get_model(self): # 重载get_model方法,必须要有!
return Article
# 建立索引的数据
def index_queryset(self, using=None):
return self.get_model().objects.all()
url(r’^searchJson/’, searchJson),
在search.html中添加:
{% load static from staticfiles %}
<script type="text/javascript" src="{% static 'jquery.min.js' %}">script>
<script>
$.ajax({
url:'/searchJson?q=框架', success(res){
console.log(res)
}
})
script>