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小技巧分享
Nov 22 Python
Python常用的爬虫技巧总结
Mar 28 Python
78行Python代码实现现微信撤回消息功能
Jul 26 Python
[原创]Python入门教程1. 基本运算【四则运算、变量、math模块等】
Oct 28 Python
12个步骤教你理解Python装饰器
Jul 01 Python
解决Jupyter无法导入已安装的 module问题
Apr 17 Python
tensorflow实现残差网络方式(mnist数据集)
May 26 Python
Python CSS选择器爬取京东网商品信息过程解析
Jun 01 Python
virtualenv介绍及简明教程
Jun 23 Python
keras输出预测值和真实值方式
Jun 27 Python
python 爬虫之selenium可视化爬虫的实现
Dec 04 Python
Python基础之元类详解
Apr 29 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 采集获取指定网址的内容
2010/01/05 PHP
windows下升级PHP到5.3.3的过程及注意事项
2010/10/12 PHP
深入PHP变量存储的详解
2013/06/13 PHP
PHP将两个关联数组合并函数提高函数效率
2014/03/18 PHP
PHP获取栏目的所有子级和孙级栏目的ID号示例
2014/04/01 PHP
PHP程序员简单的开展服务治理架构操作详解(二)
2020/05/14 PHP
javascript 兼容所有浏览器的DOM扩展功能
2012/08/01 Javascript
JS事件Event元素(兼容IE,Firefox,Chorme)
2012/11/01 Javascript
javascript中有趣的反柯里化深入分析
2012/12/05 Javascript
gridpanel动态加载数据的实例代码
2013/07/18 Javascript
js计算德州扑克牌面值的方法
2015/03/04 Javascript
获取input标签的所有属性的方法
2016/06/28 Javascript
js 文字超出长度用省略号代替,鼠标悬停并以悬浮框显示实例
2016/12/06 Javascript
vue2.x+webpack快速搭建前端项目框架详解
2017/11/30 Javascript
VS Code转换大小写、修改选中文字或代码颜色的方法
2017/12/15 Javascript
Vue+webpack实现懒加载过程解析
2020/02/17 Javascript
ES2020让代码更优美的运算符 (?.) (??)
2021/01/04 Javascript
[01:13:01]2018DOTA2亚洲邀请赛 4.4 淘汰赛 TNC vs VG 第三场
2018/04/05 DOTA
Python中__init__.py文件的作用详解
2016/09/18 Python
python使用Tkinter实现在线音乐播放器
2018/01/30 Python
Python编程中NotImplementedError的使用方法
2018/04/21 Python
python筛选出两个文件中重复行的方法
2018/05/31 Python
python实现定时发送qq消息
2019/01/18 Python
python opencv调用笔记本摄像头
2019/08/28 Python
pytorch实现对输入超过三通道的数据进行训练
2020/01/15 Python
一文轻松掌握python语言命名规范规则
2020/06/18 Python
python爬虫利器之requests库的用法(超全面的爬取网页案例)
2020/12/17 Python
随机分配座位,共50个学生,使学号相邻的同学座位不能相邻
2014/01/18 面试题
光盘行动倡议书
2014/02/02 职场文书
财务部经理岗位职责
2014/02/03 职场文书
学雷锋月活动总结
2014/04/25 职场文书
幼儿园教师师德表现自我评价
2015/03/05 职场文书
丧事答谢词大全
2015/09/30 职场文书
sqlserver2017共享功能目录路径不可改的解决方法
2021/04/16 SQL Server
Python中os模块的简单使用及重命名操作
2021/04/17 Python
html5+实现plus.io进行拍照和图片等获取
2022/06/01 HTML / CSS