美文网首页
Django 搭建博客项目(10)-搜索功能

Django 搭建博客项目(10)-搜索功能

作者: 零星瓢虫 | 来源:发表于2020-09-01 15:35 被阅读0次

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

效果图_01.png

完成搜索功能,首先想到的是通过模糊搜索对博客的 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),必须按照此格式定义,以便搜索引擎可以查找到。

效果图_02.png

编写post_text.txt 文件:

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

这里的 object 即查询到的数据模型,我们这里代表的是 Post 模型。

当上面所有的配置完成之后,既可以通过命令生成索引文件:

python manage.py rebuild_index
python manage.py update_index (如果查询不到内容) 
效果图_03.png

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

效果图_04.png

同时也可以看到在项目中生成了相应的索引文件。

到现在索引文件已经生成了,接下来则要关联搜索框,并处理相应搜索功能展示数据。

先看看在 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 相关知识。

通过上面一系列的配置已经数据获取展示,完成了搜索的整个流程。
运行程序,输入相应内容查看结果。

效果图_05.png

可以看到搜索 View 关键字分别对应了 title 和 content 的两篇博客中发现了。

但是假如现在去输入中文,比如搜索 "绘制" :

效果图_06.png

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

相关文章

网友评论

      本文标题:Django 搭建博客项目(10)-搜索功能

      本文链接:https://www.haomeiwen.com/subject/ztsudktx.html