从博客项目搭建到目前为止,可以看到首页的基本功能都已经实现,目前还剩余首页右上角的搜索功能还未实现,本篇则将对搜索功能进行实现。

完成搜索功能,首先想到的是通过模糊搜索对博客的 title 和 content 进行模糊查询匹配数据。然后将查询到的数据进行展示。但是这里不使用模糊查询,主要是因为模糊查询效率太低,需要数据库里面一条条去遍历。如果有很多数据,将会是很大的资源浪费。
那么,接下来将用到 django 提供的搜索查询库来完成首页的搜索功能。
django提供的全文检索类库
- django-haystack(容器)
- whoosh(具体的搜索引擎)
- django-haystack支持Solr,Elasticsearch,Whoosh, Xapian四种搜索引擎
这些库对数据库的数据生成索引值,通过索引值能够快速查找到搜索结果。类似于平常我们使用拼音在字典中查字的效果。django-haystack 类似于数据容器,而 whoosh 则类似于对应的索引。
首先,安装完成搜索功能需要的库。
pip install django-haystack
pip install whoosh
安装完成后,在 setting.py 中进行相应的配置:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'post',
'ckeditor',
'ckeditor_uploader',
'haystack',
]
配置相应的索引生成路径:
# 指定生成的索引路径
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
上述配置分别指定了索引使用的引擎和路径。
通过配置实时生成索引文件(根据数据库表数据的改变实时生成):
# 实时生成索引文件
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
接下来,在应用 post 模块下创建 search_indexes.py 文件,名称必须固定。因为索引库会根据名称进行查找。
编写 search_indexes.py 文件:
# coding=UTF-8
from haystack import indexes
from post.models import *
# 注意格式(模型类名+Index)
class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
# 给title,content设置索引
title = indexes.NgramField(model_attr='title')
content = indexes.NgramField(model_attr='content')
def get_model(self):
return Post
def index_queryset(self, using=None):
return self.get_model().objects.order_by('-created')
这里对上述文件作一下说明:
1 类名同样需要固定(模型 + Index);
2 text = indexes.CharField(document=True, use_template=True) 固定写法;
3 搜索通过 Post 模型的 title 和 content 进行索引,对应模型类中的相应字段。
4 get_model 必须重写,返回模型类。根据 Post 模型类进行搜索。
5 index_queryset 搜索结果按照发帖时间降序排序。
继续进行创建搜索引擎模板,格式为(project/templates/search/indexes/yourapp/post_text.txt),必须按照此格式定义,以便搜索引擎可以查找到。

编写post_text.txt 文件:
{{object.title}}
{{object.content}}
这里的 object 即查询到的数据模型,我们这里代表的是 Post 模型。
当上面所有的配置完成之后,既可以通过命令生成索引文件:
python manage.py rebuild_index
python manage.py update_index (如果查询不到内容)

可以看到这里供生成了 7 条索引,说明在 Post 模型数据库中共有 7 条数据。

同时也可以看到在项目中生成了相应的索引文件。
到现在索引文件已经生成了,接下来则要关联搜索框,并处理相应搜索功能展示数据。
先看看在 header.html 中搜索的展示以及相关请求:
<header id="header">
......
<div class="d1">
<form method="get" action="/search/">
<input type="text" name="q" placeholder="搜索">
</form>
</div>
......
</header>
需要注意的是,搜索框的 name 一定需要配置为 q 才能被搜索引擎捕获到。
在根路由 urls.py 中配置搜索请求:
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^', include('post.urls')),
url(r'ckeditor/', include('ckeditor_uploader.urls')),
url(r'search/', include('haystack.urls')),
]
搜索请求直接交给 haystack 的 urls 中去处理。
当 haystack 处理完成搜索后,会将数据交给页面去处理,这里新建的页面也需要遵守相应的创建规则,在项目根目录下的 templates/search下创建 search.html:
seach.html
{% extends 'base.html' %}
{% block main %}
<div class="archives">
{% if query %}
{% for c_post in page.object_list %}
<article class="archive-article archive-type-post">
<div class="archive-article-inner">
<header class="archive-article-header">
<a href="#" class="archive-article-date">
<time>{{ c_post.object.created|date:'Y-m' }}</time>
</a>
<h1 itemprop="name">
<a class="archive-article-title" target="_blank"
href="/post/{{ c_post.object.id }}">{{ c_post.object.title }}</a>
</h1>
</header>
</div>
</article>
{% empty %}
无记录
{% endfor %}
{% endif %}
</div>
{% endblock main %}
search.html 和 分类的结果 article.html 类似。通过页面中 page.object_list 代表搜索引擎搜索出来的结果,同时对于单个条目需要使用使用 object 获取到单个模型数据,类似与上述 post_text.txt 中的配置。
欢迎关注公众号 【python面面观】,在聊天对话框回复「博客」获取源码地址以及其他 python 相关知识。
通过上面一系列的配置已经数据获取展示,完成了搜索的整个流程。
运行程序,输入相应内容查看结果。

可以看到搜索 View 关键字分别对应了 title 和 content 的两篇博客中发现了。
但是假如现在去输入中文,比如搜索 "绘制" :

发现搜索不到对应标题中有 “绘制” 关键词的博客,那么下一篇就来解决对应中文搜索的问题。
网友评论