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 相关文章推荐
python自动化测试实例解析
Sep 28 Python
python实现计算资源图标crc值的方法
Oct 05 Python
详解python调度框架APScheduler使用
Mar 28 Python
numpy.transpose对三维数组的转置方法
Apr 17 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
Oct 21 Python
OpenCV 轮廓检测的实现方法
Jul 03 Python
python关于矩阵重复赋值覆盖问题的解决方法
Jul 19 Python
python爬虫刷访问量 2019 7月
Aug 01 Python
Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】
Oct 17 Python
python turtle 绘制太极图的实例
Dec 18 Python
SpringBoot实现登录注册常见问题解决方案
Mar 04 Python
用python爬虫批量下载pdf的实现
Dec 01 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中实现进程间通讯
2006/10/09 PHP
php下利用curl判断远程文件是否存在的实现代码
2011/10/08 PHP
一个cssQuery对象 javascript脚本实现代码
2009/07/21 Javascript
jquery validate使用攻略 第四步
2010/07/01 Javascript
javascript真的不难-回顾一下基础知识
2013/01/15 Javascript
纯js简单日历实现代码
2013/10/05 Javascript
jquery实现图片灯箱明暗的遮罩效果
2013/11/15 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
JavaScript中的null和undefined区别介绍
2015/01/01 Javascript
asp.net+js实现金额格式化
2015/02/27 Javascript
Vue 多层组件嵌套二种实现方式(测试实例)
2017/09/08 Javascript
浅谈mint-ui loadmore组件注意的问题
2017/11/08 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
Bootstrap 时间日历插件bootstrap-datetimepicker配置与应用小结
2019/05/28 Javascript
JavaScript实现矩形块大小任意缩放
2020/08/25 Javascript
[02:26]DOTA2英雄米拉娜基础教程
2013/11/25 DOTA
一篇不错的Python入门教程
2007/02/08 Python
Python基于dom操作xml数据的方法示例
2018/05/12 Python
python selenium 对浏览器标签页进行关闭和切换的方法
2018/05/21 Python
Django进阶之CSRF的解决
2018/08/01 Python
Python 中 function(#) (X)格式 和 (#)在Python3.*中的注意事项
2018/11/30 Python
python进行文件对比的方法
2018/12/24 Python
python中threading开启关闭线程操作
2020/05/02 Python
详解python的super()的作用和原理
2020/10/29 Python
英国领先的珍珠首饰品牌:Orchira
2016/09/11 全球购物
德国最大的拼图在线商店:Puzzle.de
2016/12/17 全球购物
印尼旅游网站:via
2017/11/12 全球购物
社会调查研究计划书
2014/05/01 职场文书
植树节口号
2014/06/21 职场文书
乒乓球兴趣小组活动总结
2014/07/08 职场文书
领导班子个人对照检查材料(群众路线)
2014/09/26 职场文书
党建工作整改措施
2014/10/28 职场文书
辞职信怎么写?你都知道吗?
2019/06/24 职场文书
导游词之云南-元阳梯田
2019/10/08 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
Java实现扫雷游戏详细代码讲解
2022/05/25 Java/Android