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的面向对象思想分析
Jan 14 Python
python实用代码片段收集贴
Jun 03 Python
Python 中 Meta Classes详解
Feb 13 Python
Python的爬虫程序编写框架Scrapy入门学习教程
Jul 02 Python
Python连接DB2数据库
Aug 27 Python
python字典多键值及重复键值的使用方法(详解)
Oct 31 Python
WxPython建立批量录入框窗口
Feb 27 Python
Django实现单用户登录的方法示例
Mar 28 Python
PyQt5根据控件Id获取控件对象的方法
Jun 25 Python
python 消费 kafka 数据教程
Dec 21 Python
Pytorch使用PIL和Numpy将单张图片转为Pytorch张量方式
May 25 Python
python爬取抖音视频的实例分析
Jan 19 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
抓取并下载CSS中所有图片文件的php代码
2011/09/26 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
微信红包随机生成算法php版
2016/07/21 PHP
浅谈ThinkPHP中initialize和construct的区别
2017/04/01 PHP
PHP面向对象程序设计内置标准类,普通数据类型转为对象类型示例
2019/06/12 PHP
Smarty模板配置实例简析
2019/07/20 PHP
js实现的网站首页随机公告随机公告
2007/03/14 Javascript
Jquery Validate 正则表达式实用验证代码大全
2013/08/23 Javascript
可选择和输入的下拉列表框示例
2013/11/05 Javascript
javascript实现的弹出层背景置灰-模拟(easyui dialog)
2013/12/27 Javascript
ANGULARJS中使用JQUERY分页控件
2015/09/16 Javascript
nodejs 实现钉钉ISV接入的加密解密方法
2017/01/16 NodeJs
微信小程序中form 表单提交和取值实例详解
2017/04/20 Javascript
源码分析Vue.js的监听实现教程
2017/04/23 Javascript
微信小程序日历组件calendar详解及实例
2017/06/08 Javascript
Vue filters过滤器的使用方法
2017/07/14 Javascript
Vue实现一个无限加载列表功能
2018/11/13 Javascript
JS数组Reduce方法功能与用法实例详解
2020/04/29 Javascript
微信小程序实现简单的select下拉框
2020/11/23 Javascript
[39:46]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第二场 11.25
2020/11/25 DOTA
pymssql ntext字段调用问题解决方法
2008/12/17 Python
python编写朴素贝叶斯用于文本分类
2017/12/21 Python
APIStar:一个专为Python3设计的API框架
2018/09/26 Python
python查看模块,对象的函数方法
2018/10/16 Python
Python构建图像分类识别器的方法
2019/01/12 Python
python 实现生成均匀分布的点
2019/12/05 Python
《难忘的泼水节》教学反思
2014/02/27 职场文书
幼儿园开学寄语
2014/04/03 职场文书
奠基仪式策划方案
2014/05/15 职场文书
企业安全生产标语
2014/06/06 职场文书
帮一个朋友写的求职信
2014/08/09 职场文书
客房服务员岗位职责
2015/02/09 职场文书
2016年秋季运动会通讯稿
2015/11/25 职场文书
python用海龟绘图写贪吃蛇游戏
2021/06/18 Python
教你一步步实现一个简易promise
2021/11/02 Javascript
Sql Server之数据类型详解
2022/02/28 SQL Server