Django1.9開發博客(10)- 全文搜索


Django本身不提供全文檢索的功能,但django-haystack為其提供了全文檢索的框架。 django-haystack能為Django提供whoosh,solr,Xapian和Elasticsearc四種全文檢索引擎作為后端。 其中whoosh為純python的實現,不是非常大型的應用,是沒有問題的。 本文將介紹Django1.9中通過django-haystack與whoosh集成以及whoosh的中文支持。

安裝依賴:

pip install django-haystack
pip install whoosh
pip install jieba

建立模型

我們以文章為搜索目標,現在我的app名字為blog, 模型文件是mysite/blog/models.py :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# coding=utf-8
from django.db import models
@python_2_unicode_compatible
class Post(models.Model):
class Meta:
verbose_name = u'文章'
verbose_name_plural = u'文章'
# 作者
author = models.ForeignKey(User)
# 標題
title = models.CharField(max_length=200)
# 正文
text = models.TextField()
# 標簽
tags = models.ManyToManyField(Tag)
# 分類目錄
category = models.ForeignKey(Category)
# 點擊量
click = models.IntegerField(default=0)
# 創建時間
created_date = models.DateTimeField(default=timezone.now)
# 發布時間
published_date = models.DateTimeField(blank=True, null=True)

def publish(self):
self.published_date = timezone.now()
self.save()

def __str__(self):
return self.title

search_indexes.py

在app目錄下建立一個search_indexes.py(mysite/blog/search_indexes.py)代碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from models import Post
from haystack import indexes
class PostIndex(indexes.SearchIndex, indexes.Indexable):
# 文章內容
text = indexes.CharField(document=True, use_template=True)
# 對title字段進行索引
title = indexes.CharField(model_attr='title')
def get_model(self):
return Post

def index_queryset(self, using=None):
return self.get_model().objects.all()

備注:search_indexes.py文件名不能修改,否則報錯:No fields were found in any search_indexes.

post_text.txt

因為在search_indexes.py使用了use_template=True,所以可以同時使用模板對索引字段進行定義。

如:mysite/blog/templates/search/indexes/blog/post_text.txt:

{{ object.title }}
{{ object.text }}

settings.py

1
2
3
4
5
# Application definition
INSTALLED_APPS = (
...
'haystack',
)

urls.py

1
2
3
4
5
6
7
8
9
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)),
url(r'^xadmin/', include(xadmin.site.urls), name='xadmin'),
url(r'^accounts/login/$', 'django.contrib.auth.views.login'),
url(r'^accounts/logout/$', 'django.contrib.auth.views.logout', {'next_page': '/'}),
url(r'^search/', include('haystack.urls')),
url(r'', include('blog.urls')),
)

jieba中文分詞

jieba其實已經提供了集成whoosh的ChineseAnalyzer, 也就是說不需要自己寫ChineseAnalyzer了,直接在whoosh_backend.py中直接引用就好; 同時,不推薦將whoosh_backend.py放到Lib下面,這樣移植性會有問題,自己的代碼,還是放在項目下面為妙。

1. 將文件haystack.backends.whoosh_backend.py拷貝到app下面,並重命名為whoosh_cn_backend.py, 如blog/whoosh_cn_backend.py。重點的改造有:

  • 增加:

    1
    from jieba.analyse import ChineseAnalyzer
  • 修改

    1
    schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)

2. 修改后端引擎,setting.py配置:

1
2
3
4
5
6
7
# full text search
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'blog.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}

 

重建索引

1
python manage.py rebuild_index

索引更新

最簡單的辦法就是在settings.py中添加:

1
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

 

自定義搜索示例

(1) 先定義view:

1
2
3
4
5
6
7
8
from haystack.forms import SearchForm
def full_search(request):
"""全局搜索"""
keywords = request.GET['q']
sform = SearchForm(request.GET)
posts = sform.search()
return render(request, 'blog/post_search_list.html',
{'posts': posts, 'list_header': '關鍵字 \'{}\' 搜索結果'.format(keywords)})

(2) 然后在template頁面中:

1
2
3
4
5
6
7
8
9
10
11
<!-- searchbox START -->
<div id="searchbox">
<form action="{% url 'blog.views.full_search' %}" method="get">
<div class="content">
<label>
<input type="text" class="textfield searchtip" name="q" size="24" value="">
</label>
<input type="submit" class="button" value="">
</div>
</form>
</div>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM