Django实现全文检索的方法(支持中文)


Posted in Python onMay 14, 2018

PS: 我的检索是在文章模块下 forum/article

第一步:先安装需要的包:

pip install django-haystack
pip install whoosh
pip install jieba

第二步: 配置需要的文件 settings.py

添加haystack应用模块

INSTALLED_APPS = (
   ...
  'haystack',
   ...
)

在settings.py 末尾添加

HAYSTACK_CONNECTIONS = {
  'default': {
    'ENGINE': 'article.whoosh_cn_backend.WhooshEngine',
    'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
  },
}
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'  # 索引自动更新

第三步: 配置url路径

在 forum/forum/urls.py中包含search路径

url(r'^search/', include('haystack.urls')),

第四步:建立模型

forum/article/models.py

class Article(models.Model):
  '''
  文章数据模型
  '''
  id = models.AutoField(primary_key=True,verbose_name='文章编号')
  title = models.CharField(max_length=50,verbose_name='文章标题')
  content = MDTextField()
  publish_time = models.DateTimeField(auto_now_add=True,verbose_name='发表时间')
  last_update_time = models.DateTimeField(auto_now=True,verbose_name='最后一次修改时间')
  status = models.IntegerField(u'状态', default=1) 
  read_count = models.IntegerField(default=0,verbose_name='阅读次数')
  comment_count = models.IntegerField(default=0,verbose_name='评论次数')

  #关联用户
  user = models.ForeignKey(User,on_delete=models.CASCADE,verbose_name='用户')
  subject = models.ForeignKey(Subject, null=True, blank=True, on_delete=models.CASCADE,
                verbose_name='属于哪一个专题')

第五步:设置为那个class建立索引

如果你想针对某个app例如mainapp做全文检索,则必须在mainapp的目录下面建立search_indexes.py文件,文件名不能修改
例:forum/article/search_indexes.py模块

from article.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)

每个索引里面必须有且只能有一个字段为document=True

第六步: 确定我们需要的属性:

新建yourapp/templates/search/indexes/yourapp/article_text.txt来指明需要属性

例: article/templates/search/indexes/yourapp/article_text.txt

{{ object.title }} # 文章标题
{{ object.user.username }} # 文章作者
{{ object.content }} # 文章内容

第七步: 把搜索引擎放入项目下

例: forum/article/whoosh_cn_backend.py

将文件whoosh_backend.py(例: 我的python路径E:\python\Lib\site-packages\haystack\backends\whoosh_backend.py
)放到article下,并重命名为whoosh_cn_backend.py,例如blog/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)

成功引入jieba分词

第八步: 前端页面配置

templates/base.html (搜索页面)

<form class="navbar-form navbar-left" action="/search/" method="get">
        <div class="form-group">
          <input type="text" class="form-control" name="q" placeholder="请输入搜索的内容" value=""/>
        </div>
        <input type="submit" value="搜索">
      </form>

结果展示页面(forum/article/templates/search/search.html)

{% extends 'base.html' %}

{% block title %}搜索结果{% endblock %}

{% block content %}
<div class="container" id="content">
  <div class="search-body">

  <form method="get" action="">
    <table>
      <tr>
        <td>
          <label for="id_q"></label>
        </td>
        <td>
          <input class="form-control" id="id_q" name="q" type="search" value="{{ query }}" />
        </td>

        <td> </td>
        <td>
          <button class="btn btn-defaul" type="submit"><span class="glyphicon glyphicon-search">搜索</span></button>
        </td>
      </tr>


    </table>
</form>
    {% if query %}
      <h3>搜索结果</h3>

      <table class="table">
      <tr>

         {% for result in page.object_list %}
           <td>
        <p>
          <a href="{% url 'article:article_detail' article_id=result.object.id %}" rel="external nofollow" >
            {{ result.object.title }}</a>
        </p> 作者: <a href="{% url 'user:user_index' result.object.user.id %}" rel="external nofollow" >{{ result.object.user.username }}</a>
        <p>{{ result.object.content | safe | truncatechars_html:40 }}</p>
      </td>
      </tr>

      {% empty %}
        <p>没有得到想要的结果哦.</p>
      {% endfor %}
      </table>


      {% if page.has_previous or page.has_next %}
        <div>
          {% if page.has_previous %}<a href="?q={{ query }}&page={{ page.previous_page_number }}" rel="external nofollow" >{% endif %}« 上一页{% if page.has_previous %}</a>{% endif %}
          |
          {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}" rel="external nofollow" >{% endif %}下一页 »{% if page.has_next %}</a>{% endif %}
        </div>
      {% endif %}
    {% else %}
      {# Show some example queries to run, maybe query syntax, something else? #}
    {% endif %}


  </div>

</div>
{% endblock %}

第九步: 建立索引

python manage.py rebuild_index

建立成功会自行生成一个forum/whoosh_index的文件夹

第十步: 运行程序

python manage.py runserver

PS: 模板样式可以自行调整

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python33 urllib2使用方法细节讲解
Dec 03 Python
Python中处理字符串的相关的len()方法的使用简介
May 19 Python
python文件特定行插入和替换实例详解
Jul 12 Python
使用Python写一个贪吃蛇游戏实例代码
Aug 21 Python
Python实现Pig Latin小游戏实例代码
Feb 02 Python
python将每个单词按空格分开并保存到文件中
Mar 19 Python
python实现图书借阅系统
Feb 20 Python
Python unittest工作原理和使用过程解析
Feb 24 Python
Python气泡提示与标签的实现
Apr 01 Python
python使用smtplib模块发送邮件
Dec 17 Python
Python 恐龙跑跑小游戏实现流程
Feb 15 Python
使用Python拟合函数曲线
Apr 14 Python
如何用python整理附件
May 13 #Python
Python基于dom操作xml数据的方法示例
May 12 #Python
Python实现使用卷积提取图片轮廓功能示例
May 12 #Python
在cmd中运行.py文件: python的操作步骤
May 12 #Python
对命令行模式与python交互模式介绍
May 12 #Python
python执行系统命令后获取返回值的几种方式集合
May 12 #Python
在CMD命令行中运行python脚本的方法
May 12 #Python
You might like
php 字符转义 注意事项
2009/05/27 PHP
php加水印的代码(支持半透明透明打水印,支持png透明背景)
2013/01/17 PHP
thinkphp实现多语言功能(语言包)
2014/03/04 PHP
PHP中ini_set与ini_get用法实例
2014/11/04 PHP
php session 写入数据库
2016/02/13 PHP
php根据年月获取当月天数及日期数组的方法
2016/11/30 PHP
PHP房贷计算器实例代码,等额本息,等额本金
2017/04/01 PHP
php出租房数据管理及搜索页面
2017/05/23 PHP
Convert Seconds To Hours
2007/06/16 Javascript
鼠标拖拽移动子窗体的JS实现
2014/02/25 Javascript
一些老手都不一定知道的JavaScript技巧
2014/05/06 Javascript
通过js为元素添加多项样式,浏览器全兼容写法
2014/08/30 Javascript
jquery通过ajax加载一段文本内容的方法
2015/01/15 Javascript
jQuery实现textarea自动增长宽高的方法
2015/12/18 Javascript
vue实现双向绑定和依赖收集遇到的坑
2018/11/29 Javascript
JS使用JSON.parse(),JSON.stringify()实现对对象的深拷贝功能分析
2019/03/06 Javascript
JavaScript函数式编程(Functional Programming)箭头函数(Arrow functions)用法分析
2019/05/22 Javascript
vue 实现element-ui中的加载中状态
2020/11/11 Javascript
详解JavaScript原型与原型链
2020/11/16 Javascript
python实现查询IP地址所在地
2015/03/29 Python
基于Python socket的端口扫描程序实例代码
2018/02/09 Python
Python中文件的读取和写入操作
2018/04/27 Python
Python数据类型之列表和元组的方法实例详解
2019/07/08 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
Python实现TCP通信的示例代码
2019/09/09 Python
详解如何修改python中字典的键和值
2020/09/29 Python
网络教育自我鉴定
2013/11/01 职场文书
会计电算化个人自我评价
2013/11/17 职场文书
妇联主席先进事迹
2014/05/18 职场文书
七夕相亲活动策划方案
2014/08/31 职场文书
钱塘江大潮导游词
2015/02/03 职场文书
小平您好观后感
2015/06/09 职场文书
运动会班级前导词
2015/07/20 职场文书
当你焦虑迷茫时,请读读这6句话
2019/07/24 职场文书
OpenCV-Python实现图像平滑处理操作
2021/06/08 Python
JS中如何优雅的使用async await详解
2021/10/05 Javascript