Django自学笔记之全文检索

1.依次安装以下包: 

pip install django-haystack
pip install whoosh
pip install jieba

2.修改settings.py文件: 

  • 添加应用 
INSTALLED_APPS = (
    ...
    'haystack',
)

 添加搜索引擎 

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    }
}

#自动生成索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

3.在应用目录下建立search_indexes.py文件:

#!/usr/bin/env python
# coding=utf-8

from haystack import indexes
from .models import HeroInfo

class HeroInfoIndex(indexes.SearchIndex,indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)

    def get_model(self):
        # 哪个表,这里查找英雄表
        return HeroInfo

    def index_queryset(self, using=None):
        # 基于哪些数据进行检索
        return self.get_model().objects.all()

4.在目录“templates/search/indexes/应用名称/”下创建“模型类名称_text.txt”文件,

(此例应用名称为:booktest,文本文件为:heroinfo_text.txt):

这里列出了要对哪些列的内容进行检索(注意字段是CharField类型的才可以)

# 我们在models.py中创建的HeroInfo,hname和hcontent是CharField类型
class HeroInfo(models.Model):
    hname = models.CharField('名字',max_length=20)
    hgender = models.BooleanField(default=True)
    isDelete = models.BooleanField(default=False)
    hcontent = models.CharField('英雄介绍',max_length=1000)
    hbook = models.ForeignKey('BookInfo',verbose_name='所属图书',on_delete=models.CASCADE)
# /templates/search/indexes/booktest/heroinfo_text.txt
# heroinfo_text.txt中:
{{object.hname}}
{{object.hcontent}}

5.在目录“templates/search/”下建立检索的结果页面search.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>检索的结果页面</title>
</head>
<body>
搜索的关键词:{{query}}
{% if query %}
    <h3>搜索结果如下:</h3>
    {% if not page.object_list|length == 0 %}
    <table border="1">
        <tr>
            <th width="50%">姓名</th>
            <th width="50%">英雄介绍</th>
        </tr>
        {% for result in page.object_list %}
                <tr>
                    <th width="50%"><a href="/search/{{ result.object.id }}/">{{ result.object.hname }}</a></th>
                    <th width="80%"><a href="/search/{{ result.object.id }}/">{{ result.object.hcontent }}</a></th>
                </tr>
        {% endfor %}
        </table>
    {{page}}
    共{{page.object_list|length}}条数据
        {% if page.has_previous or page.has_next %}
            <div>
                {% if page.has_previous %}<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; 上一页{% if page.has_previous %}</a>{% endif %}
            |
                {% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}下一页 &raquo;{% if page.has_next %}</a>{% endif %}
            </div>
        {% endif %}
    {% elif page.object_list|length == 0 %}
        <p>啥也没找到啊</p>
    {% endif %}
{% else %}
未输入关键词,请<a href="/search_index/">返回查询页</a>
{% endif %}
</body>
</html>

在目录“templates”下建立搜索输入内容界面search_index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method='get' action="/search/" target="_blank">
    <input type="text" name="q" placeholder="请输入至少两个字">
    <input type="submit" value="查询">
</form>

</body>
</html>

6.设置视图views.py文件:

from django.shortcuts import render
from django.http import HttpResponse
from .models import *

# 搜索输入内容界面视图
def search_index(request):
    return render(request,'search_index.html')

# 这个是点击查询结果后显示的页面
def search_result(request,id):
    result = HeroInfo.objects.filter(pk=id)
    li = []
    for i in result:
        li.append('英雄id:'+id)
        li.append('<br>')
        li.append('<br>')
        li.append('英雄姓名:'+i.hname)
        li.append('<br>')
        li.append('<br>')
        li.append('英雄介绍:'+i.hcontent)
        li.append('<br>')
        li.append('<br>')
        li.append('<a href="/search_index/">返回查询首页</a>')
        return HttpResponse(li)

7.建立ChineseAnalyzer.py文件:

  • 保存在haystack的安装文件夹下,路径大致如“.....Lib/site-packages/haystack/backends”
# encoding: utf-8
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()

8.在以上目录里复制whoosh_backend.py文件,改名为whoosh_cn_backend.py:

先导入:from .ChineseAnalyzer import ChineseAnalyzer
然后查找
analyzer=StemmingAnalyzer()
改为
analyzer=ChineseAnalyzer()

9.生成索引:

  • 初始化索引数据
python manage.py rebuild_index

 10.启动服务:

python manage.py runserver

输入网址查看:http://127.0.0.1:8000/search_index/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章