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下调用pytesseract识别某网站验证码的实现方法
Jun 06 Python
NumPy 如何生成多维数组的方法
Feb 05 Python
使用python读取txt文件的内容,并删除重复的行数方法
Apr 18 Python
tensorflow求导和梯度计算实例
Jan 23 Python
Python3.x+pyqtgraph实现数据可视化教程
Mar 14 Python
如何在windows下安装配置python工具Ulipad
Oct 27 Python
用ldap作为django后端用户登录验证的实现
Dec 07 Python
Python关于拓扑排序知识点讲解
Jan 04 Python
Python利用socket模块开发简单的端口扫描工具的实现
Jan 27 Python
pandas中DataFrame重置索引的几种方法
May 24 Python
python获取对象信息的实例详解
Jul 07 Python
Python中的socket网络模块介绍
Jul 23 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中两个float(浮点数)比较实例分析
2015/09/27 PHP
PHP分页显示的方法分析【附PHP通用分页类】
2018/05/10 PHP
js 未结束的字符串常量错误解决方法
2010/06/13 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
2013/05/03 Javascript
JavaScript prototype 使用介绍
2013/08/29 Javascript
javascript中Object使用详解
2015/01/26 Javascript
JavaScript通过function定义对象并给对象添加toString()方法实例分析
2015/03/23 Javascript
原生js结合html5制作小飞龙的简易跳球
2015/03/30 Javascript
JavaScript三元运算符的多种使用技巧
2015/04/16 Javascript
基于jQuery全屏焦点图左右切换插件responsiveslides
2015/09/07 Javascript
举例讲解JavaScript中关于对象操作的相关知识
2015/11/16 Javascript
3分钟快速搭建nodejs本地服务器方法运行测试html/js
2017/04/01 NodeJs
js实现随机数字字母验证码
2017/06/19 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
2018/05/09 Javascript
JavaScript自动生成 年月范围 选择功能完整示例【基于jQuery插件】
2019/09/03 jQuery
layui--select使用以及下拉框实现键盘选择的例子
2019/09/24 Javascript
layer弹出层取消遮罩的方法
2019/09/25 Javascript
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
2021/01/22 Vue.js
[03:02]2014DOTA2西雅图邀请赛 让队员自己告诉你DK NAVI备战情况
2014/07/08 DOTA
python基于Tkinter库实现简单文本编辑器实例
2015/05/05 Python
Python反射用法实例简析
2017/12/22 Python
Python实现识别手写数字大纲
2018/01/29 Python
Python2和Python3.6环境解决共存问题
2018/11/09 Python
用Python批量把文件复制到另一个文件夹的实现方法
2019/08/16 Python
Python3 翻转二叉树的实现
2019/09/30 Python
pytorch 改变tensor尺寸的实现
2020/01/03 Python
keras小技巧——获取某一个网络层的输出方式
2020/05/23 Python
CSS3弹性布局内容对齐(justify-content)属性使用详解
2017/07/31 HTML / CSS
阿波罗盒子:Apollo Box
2017/08/14 全球购物
Currentbody西班牙:美容仪专家
2019/09/28 全球购物
linux面试题参考答案(1)
2016/01/22 面试题
J2EE的优越性主要表现在哪些方面
2016/03/28 面试题
教学改革实施方案
2014/03/31 职场文书
房产买卖委托公证书
2014/04/04 职场文书
努力学习演讲稿
2014/05/10 职场文书
html+css合并表格边框的示例代码
2021/03/31 HTML / CSS