正文
作者:chenyvehtung
原文:https://chenyvehtung.github.io/2015/09/11/django-haystack-search.html
背景介绍
本人在开发一个Django应用时,其中的一个需求是搜索功能,而Django本身并没有自带搜索模块,所以必须自己实现。显然,最简单粗暴的方法就是,通过暴搜数据库来查找接收到的文字输入,当数据量相对大一点时,这种方法是很不可取的。本文将要介绍的这个方法是使用
Django-haystack
这个全文检索框架结合
Whoosh
检索引擎以及
Jieba(结巴)
中文分词来实现的。
-
Whoosh
是一个纯python实现的全文搜索组件。Whoosh不但功能完善,还非常的快。
-
Haystack
是一个第三方的app,专门用来为Django增加全文检索功能,让你可以方便地对model里面的内容进行索引,搜索,简化你的工作。并且Django-haystack设计为支持whoosh,solr,Xapian,Elasticsearc四种全文检索引擎后端,属于一种全文检索的框架。
-
Jieba
是一个Python中文分词组件,其包含多种功能,本文使用了其中的"ChineseAnalyzer for Whoosh搜索引擎"功能。
安装依赖
pip install django-haystack
pip install whoosh
pip install jieba
具体实现
前端建立搜索框(base.html)
class="form-group">
type="text" class="form-control" name="q" placeholder="输入搜索内容" value=""/>
class
=
"glyphicon glyphicon-search"
>
添加URL(urls.py)
在
urls
.
py
中,添加如下内容到
urlpatterns
url(r'^search/', include('haystack.urls')),
这样,上一步骤中的action将会指向haystack.urls
建立模型(models.py)
我们将对此文章类中的title和text进行搜索
class Article(models.
Model):
class Meta:
verbose_name = u'文章'
verbose_name_plural = u'文章'
article_type = (
(1, u'失恋'),
(2, u'暗恋'),
(3, u'异地恋'),
(4, u'爱恋'),
)
author = models.ForeignKey(settings.AUTH_USER_MODEL)
title = models.CharField(u'文章标题',max_length=200)
text = models.TextField(u'文章内容')
choose_type = models.IntegerField(u'板块选择',choices=article_type, default=article_type[0][0])
created_time = models.DateTimeField(u'发布时间',default=timezone.now, editable=False)
# article valid or invalid
status
= models.IntegerField(u'状态',default=1)
image = models.ImageField(u'文章图片',upload_to='images/articleimg', blank=True)
def __unicode__(self):
return self.title
选定模型(search_indexes.py)
在models.py所在目录下,新建search_indexes.py,用来确定我们将选定那个class来建立索引。
#! /usr/bin/python
# -*- coding: utf-8 -*-
from misslove.models import Article
from haystack import indexes
class
ArticleIndex(indexes.SearchIndex, indexes.Indexable):
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.filter(status=1)
确定属性(article_text.txt)
此步骤中,我们需要建立
classname_text
.
txt
,并在其中指明我们需要对选定类中的哪些属性进行索引。该文件所在的路径应该是
templates
/
search
/
indexes
/
appname
。如本项目为:
/templates/
search
/
indexes
/
misslove
/
article_text
.
txt
,并在文件中写入(
请去除其中的"",由于模板语言冲突
)
{{ object.title }}
{{ object.text }}
其中的
title
和
text
就是我们想要建立索引的文章标题和文章内容。
添加搜索引擎到项目中(whoosh
cn
backend.py)
由于whoosh搜索引擎无法对中文进行搜索,所以我们需要使用jieba分词来作为whoosh的ChineseAnalyzer,这样就必须对原有的代码进行修改。考虑到安全性以及可移植性,我们可以把
whoosh_backend
.
py
拷贝到项目下再进行修改。
将
whoosh_backend
.
py
拷贝到
models
.
py
所在的目录下,并将其重命名为
whoosh_cn_backend
.
py
,然后,在该文件中添加
from jieba.analyse import ChineseAnalyzer
找到
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)
这样,便成功地为whoosh引擎添加了jieba分词
选定搜索引擎(settings.py)
我们需要在settings.py中添加haystack应用
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles'