该博客最开始采用的模板是并不包括搜索功能的,在主页只有主页、归档和分类三个部分。最后博主自己添加了搜索框,不过其实不太想让大家使用这个功能,因此将搜索框隐藏了,只有再点击搜索时,才会显现出来。但是这个添加匹配的不太好,导致手机端会有对不齐的现象,以后前端学好了再来修复这个bug。

博客的搜索功能简单来实现的话,通过查询功能查找到符合关键字的对象。但是,对于一个搜索引擎来说,至少应该能够根据用户的搜索关键词对搜索结果进行排序以及高亮关键字。现在我们就来使用 django-haystack 实现这些特性。

django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr、Elasticsearch、Whoosh、Xapian 等多种搜索引擎,配合著名的中文自然语言处理库 jieba 分词,就可以为我们的博客提供一个效s果不错的博客文章搜索系统。

1、安装相关软件

进入我们的虚拟环境,安装以下依赖:

pip install whoosh django-haystack jieba
  • Whoosh。Whoosh 是一个由纯 Python 实现的全文搜索引擎,没有二进制文件等,比较小巧,配置简单方便。
  • jieba 中文分词。由于 Whoosh 自带的是英文分词,对中文的分词支持不是太好,所以使用 jieba 替换Whoosh 的分词组件。

2、配置 Haystack

安装完成后,需要在setting.py中进行相关配置:

INSTALLED_APPS = ['django.contrib.admin',# 其它 app...'haystack',
]HAYSTACK_CONNECTIONS = {'default': {'ENGINE': 'blog.whoosh_cn_backend.WhooshEngine','PATH': os.path.join(BASE_DIR, 'whoosh_index'),},
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

HAYSTACK_CONNECTIONS 的 ENGINE 指定了 django haystack 使用的搜索引擎,这里我们使用了 blog.whoosh_cn_backend.WhooshEngine,虽然目前这个引擎还不存在,但我们接下来会创建它。PATH 指定了索引文件需要存放的位置,我们设置为项目根目录 BASE_DIR 下的 whoosh_index 文件夹(在建立索引是会自动创建)。

HAYSTACK_SEARCH_RESULTS_PER_PAGE 指定如何对搜索结果分页,这里设置为每 10 项结果为一页。

HAYSTACK_SIGNAL_PROCESSOR 指定什么时候更新索引,这里我们使用 haystack.signals.RealtimeSignalProcessor,作用是每当有文章更新时就更新索引。由于博客文章更新不会太频繁,因此实时更新没有问题。

3、处理数据

接下来就要告诉 django haystack 使用那些数据建立索引以及如何存放索引。如果要对 blog 应用下的数据进行全文检索,做法是在 myblog 应用下建立一个 search_indexes.py 文件,写上如下代码:

from haystack import indexes
from myblog.models import Blogclass BlogIndex(indexes.SearchIndex, indexes.Indexable):text = indexes.CharField(document=True, use_template=True)def get_model(self):return Blogdef index_queryset(self, using=None):return self.get_model().objects.all()

这是 django haystack 的规定。要相对某个 app 下的数据进行全文检索,就要在该 app 下创建一个 search_indexes.py 文件,然后创建一个 XXIndex 类(XX 为含有被检索数据的模型,如这里的 Post),并且继承 SearchIndex 和 Indexable。

为什么要创建索引?索引就像是一本书的目录,可以为读者提供更快速的导航与查找。在这里也是同样的道理,当数据量非常大的时候,若要从这些数据里找出所有的满足搜索条件的几乎是不太可能的,将会给服务器带来极大的负担。所以我们需要为指定的数据添加一个索引(目录),在这里是为 Post 创建一个索引,索引的实现细节是我们不需要关心的,我们只关心为哪些字段创建索引,如何指定。

每个索引里面必须有且只能有一个字段为 document=True,这代表 django haystack 和搜索引擎将使用此字段的内容作为索引进行检索(primary field)。注意,如果使用一个字段设置了document=True,则一般约定此字段名为text,这是在 SearchIndex 类里面一贯的命名,以防止后台混乱,当然名字你也可以随便改,不过不建议改。

并且,haystack 提供了use_template=True 在 text 字段中,这样就允许我们使用数据模板去建立搜索引擎索引的文件,说得通俗点就是索引里面需要存放一些什么东西,例如 Post 的 title 字段,这样我们可以通过 title 内容来检索 Post 数据了。举个例子,假如你搜索 Python ,那么就可以检索出 title 中含有 Python 的Post了,怎么样是不是很简单?数据模板的路径为 templates/search/indexes/youapp/\<model_name>_text.txt(例如 templates/search/indexes/myblog/post_text.txt),其内容为:

{{ object.title }}
{{ object.content }}

这个数据模板的作用是对 Post.title、Post.body 这两个字段建立索引,当检索的时候会对这两个字段做全文检索匹配,然后将匹配的结果排序后作为搜索结果返回。

4、 配置 URL

接下来就是配置 URL,搜索的视图函数和 URL 模式 django haystack 都已经帮我们写好了,只需要项目的 urls.py 中包含它:

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

5、修改搜索表单

修改一下搜索表单,让它提交数据到 django haystack 搜索视图对应的 URL:

<form action="{% url 'haystack_search' %}"><input id="unit" type="search" name="q" placeholder="搜索">
</form>

6、创建搜索结果页面

haystack_search 视图函数会将搜索结果传递给模板 search/search.html,因此创建这个模板文件,对搜索结果进行渲染:

{% extends 'base.html' %}{% load highlight %}{% block content %}
<div class="content-wrap">{% for blog in page.object_list %}<div><a href="{% url 'blog_id' blog.object.id %}"><h3>{{ forloop.counter }}、{% highlight blog.object.title with query %}</h3></a><div style="word-wrap: break-word">{% highlight blog.object.content with query %}</div>{% if forloop.counter == page.object_list|length %}{% else %}<hr>{% endif %}</div>
{% empty %}<div class="no-post">没有搜索到相关内容,请重新搜索</div>
{% endfor %}</div>
{% endblock %}

由于 haystack 对搜索结果做了分页,传给模板的变量是一个 page 对象,所以我们从 page 中取出这一页对应的搜索结果,然后对其循环显示,即 {% for blog in page.object_list %}。另外要取得 博客以显示博客的数据如标题、正文,需要从 blog的 object 属性中获取。query 变量的值即为用户搜索的关键词。

7、关键词高亮

注意到百度的搜索结果页面,含有用户搜索的关键词的地方都是被标红的,在 django haystack 中实现这个效果也非常简单,只需要使用 {% highlight %} 模板标签即可,其用法如下:

# 使用默认值
{% highlight result.summary with query %}  # 这里我们为 {{ result.summary }} 里所有的 {{ query }} 指定了一个<div></div>标签,并且将class设置为highlight_me_please,这样就可以自己通过CSS为{{ query }}添加高亮效果了,怎么样,是不是很科学呢
{% highlight result.summary with query html_tag "div" css_class "highlight_me_please" %}  # 可以 max_length 限制最终{{ result.summary }} 被高亮处理后的长度
{% highlight result.summary with query max_length 40 %}  

8、修改搜索引擎为中文分词

我们使用 Whoosh 作为搜索引擎,但在 django haystack 中为 Whoosh 指定的分词器是英文分词器,可能会使得搜索结果不理想,我们把这个分词器替换成 jieba 中文分词器。从你安装的 haystack 中把 haystack/backends/whoosh_backends.py 文件拷贝到 blog/ 下,重命名为 whoosh_cn_backends.py(之前我们在 settings.py 中 的 HAYSTACK_CONNECTIONS 指定的就是这个文件),然后找到如下一行代码:

schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True)

将其中的 analyzer 改为 ChineseAnalyzer,当然为了使用它,你需要在文件顶部引入:from jieba.analyse import ChineseAnalyzer

9、建立索引文件

最后一步就是建立索引文件了,运行命令 python manage.py rebuild_index 就可以建立索引文件了。

最后,我们可以通过搜索命令给定关键词进行搜索,比如搜索”博客“,便会得到如下结果:

但是,我们可以看到博客的标题只有关键词, 关键词之前的内容被…替代了。这显然不是我们想要的效果,接下来我们通过修改源码来实现博客标题的完全显示以及对搜索结果的分页并使其序号连续显示。

——————————————————————————————————————————

项目的完整代码:django_blog
觉得有用的欢迎给个star。

Django开发个人博客网站——19、通过Django Haystack实现搜索功能(上)相关推荐

  1. Django开发个人博客网站——1、开发环境

    1.写在前面的话 刚最开始自学python,然后学习django框架,中间断断续续有几个月的时间,是时候通过一个项目来检验下自己的学习成果了.既然学习了django web框架,那很自然的就是想到要搭 ...

  2. Django开发个人博客网站

    本文介绍如何使用Django 从零开始搭建一个专属自己的高度定制化的博客平台. 1.网站示例 你可以到这里查看博主的博客示例:永春小站 网站项目地址:https://github.com/yooong ...

  3. Django开发个人博客网站——3、使用pycharm创建博客项目

    1.pycharm介绍 PyCharm是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试.语法高亮.Project管理.代码跳转.智能提示.自动完 ...

  4. Django开发个人博客网站——12、实现不同大小的标签云样式

    1.创建标签页面 与上一节中创建归档页面一样,这里就不再赘述了,直接给出程序代码. tags.html {% extends 'base.html' %}{% block title %} 标签云 { ...

  5. Django开发个人博客网站——8、博客首页的开发

    现在我们进入博客的首页127.0.0.1:8000, 发现还是欢迎页面,因为我们还没有给博客添加任何模板,也就是前端html页面. 博客前端模板托管在GitHub:django_blog_templa ...

  6. Django开发个人博客网站——16、给博客添加上评论功能

    博客中的评论系统其实是个很复杂的东西,但是网上已经有现成的轮子了,比如django-contrib-comments,可以直接拿过来用.但是我这里博客主要是给自己看的,并不想有太复杂的互动内容,因此, ...

  7. Thinkphp5开发个人博客网站源码+技术交流分享

    正文: Thinkphp5开发个人博客网站源码+技术交流分享,TP5.0博客系统源码,支持QQ一键登录,. 安装说明: 1.将程序上传到网站根目录. 2.导入数据库文件 boke.sql 3.appl ...

  8. html编写个人博客_Django 开发简易博客网站

    本篇使用 Django 开发博客网站的核心内容,涉及 Django .MySQL .WampServer :我比较喜欢 Django 框架的 MVC (模型.视图.控制器)的软件设计模式,其中我最喜欢 ...

  9. django开发个人博客

    1.查询所有的数据 def new_list(request):articles=Article.object.order_by("-date")return render_to_ ...

最新文章

  1. Python使用matplotlib保存图像时发生自动裁剪丢了部分标签信息解决方案(plt.savefig保存时丢失了部分标签字符)
  2. Setup 和Hold (建立时间和保持时间)解析
  3. Linux不能上网ping:unknown host问题怎么解决?
  4. 再见了微服务!全面拥抱 DDD 思想真正的价值!
  5. ubuntu14.04LS中安装sogouPingyin
  6. nginx+tomcat
  7. javaScript事件(一)事件流
  8. 7-1 FireTruck 消防车 uva208
  9. mysql查询条件是小数 查不到6.28_28.mysql数据库之查询
  10. 语音识别软件哪个好?好用的语音识别软件盘点
  11. 小米商城项目解析(完)
  12. Android SDK Manager Proxy on MAC
  13. 【生信技能树】GEO数据库挖掘 P5
  14. python pytz模块_python pytz
  15. Python 之 解析xml
  16. java 打印 日历 详细 注解_Java实现按年月打印日历功能【基于Calendar】
  17. 为什么电脑屏幕会横过来_电脑屏幕横过来了怎么办
  18. 简练软考知识点整理-激励理论之赫兹伯格双因素理论
  19. 托福高频真词List10 // 附托福TPO阅读真题
  20. python实现数组的全组合以及全排列

热门文章

  1. windows驱动开发5:WDK Demo:avstream avscamera
  2. ARCGIS10.2加载天地图不显示
  3. 高速C/C++编译工具(ccache)
  4. 追求卓越之--arm MMU详解
  5. 使用深度优先搜索算法解决迷宫问题
  6. P2P归零、长租暴雷,盘盘那些互联网洗白过的伪创新
  7. Asp.net Core 入门实战
  8. 对整行tr除最后一列外的每一列设置点击事件
  9. 微信抢红包代码 python_Python实现的微信红包提醒功能示例
  10. 使用正则表达式批量替换掉 空格及换行符