Django 博客实现简单的全文搜索

作者:HelloGitHub-追梦人物

文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库

搜索是一个复杂的功能,但对于一些简单的搜索任务,我们可以使用 Django Model 层提供的一些内置方法来完成。现在我们来为我们的博客提供一个简单的搜索功能。

概述

博客文章通常包含标题和正文两个部分。当用户输入某个关键词进行搜索后,我们希望为用户显示标题和正文中含有被搜索关键词的全部文章。整个搜索的过程如下:

  1. 用户在搜素框中输入搜索关键词,假设为 “django”,然后用户点击了搜索按钮提交其输入的结果到服务器。
  2. 服务器接收到用户输入的搜索关键词 “django” 后去数据库查找文章标题和正文中含有该关键词的全部文章。
  3. 服务器将查询结果返回给用户。

整个过程就是这样,下面来看看 Django 如何用实现这些过程。

将关键词提交给服务器

先来回顾一下我们的 Django 博客的 Post(文章)模型:

blog/models.py

class Post(models.Model):
    # 标题
    title = models.CharField("标题", max_length=70)
    # 正文
    body = models.TextField("正文")

    # 其他属性...

    def __str__(self):
        return self.title

先看到第 1 步,用户在搜索框输入搜索关键词,因此我们要在博客上为用户提供一个搜索表单,HTML 表单代码大概像这样:

templates/base.html

<form role="search" method="get" id="searchform" action="{% url 'blog:search' %}">
  <input type="search" name="q" placeholder="搜索" required>
  <button type="submit"><span class="ion-ios-search-strong"></span></button>
</form>

特别注意这里 <input type="search" name="q" placeholder="搜索" required> 中的 name 属性,当用户在这个 input 中输入搜索内容并提交表单后,键入的数据会以键值对的形式提交服务器,这个键的名字就是通过 name 属性指定的。这样服务器就可以根据 name 的值来取得用户输入的内容。

用户输入了搜索关键词并点击了搜索按钮后,数据就被发送给了 Django 后台服务器。表单的 action 属性的值为 {% url ‘blog:search‘ %}(虽然我们还没有写这个视图函数),表明用户提交的结果将被发送给 blog 应用下 search 视图函数对应的 URL。

查找含有搜索关键词的文章

搜索的功能将由 search 视图函数提供,代码写在 blog/views.py 里:

blog/views.py

from django.contrib import messages

def search(request):
    q = request.GET.get('q')

    if not q:
        error_msg = "请输入搜索关键词"
        messages.add_message(request, messages.ERROR, error_msg, extra_tags='danger')
        return redirect('blog:index')

    post_list = Post.objects.filter(Q(title__icontains=q) | Q(body__icontains=q))
    return render(request, 'blog/index.html', {'post_list': post_list})

首先我们使用 request.GET.get(‘q‘) 获取到用户提交的搜索关键词。用户通过表单 get 方法提交的数据 Django 为我们保存在 request.GET 里,这是一个类似于 Python 字典的对象,所以我们使用 get 方法从字典里取出键 q 对应的值,即用户的搜索关键词。这里字典的键之所以叫 q 是因为我们的表单中搜索框 input 的 name 属性的值是 q,如果修改了 name 属性的值,那么这个键的名称也要相应修改。

接下来我们做了一个小小的校验,如果用户没有输入搜索关键词而提交了表单,我们就无需执行查询,我们给给用户发一条错误提醒消息,这里使用了 django messages 应用,这在 交流的桥梁:评论功能 中讲过。然后将用户重定向到首页。这里的 redirect 函数也在那篇教程中讲过。

如果用户输入了搜索关键词,我们就通过 filter 方法从数据库里过滤出符合条件的所有文章。这里的过滤条件是 title__icontains=q,即 title 中包含(contains)关键字 q,前缀 i 表示不区分大小写。这里 icontains 是查询表达式(Field lookups),我们在之前也使用过其他类似的查询表达式,其用法是在模型需要筛选的属性后面跟上两个下划线。Django 内置了很多查询表达式,建议过一遍 Django 官方留个印象,了解每个表达式的作用,以后碰到相关的需求就可以快速定位到文档查询其用途 Field lookups

此外我们这里从 from django.db.models 中引入了一个新的东西:Q 对象。Q 对象用于包装查询表达式,其作用是为了提供复杂的查询逻辑。例如这里 Q(title__icontains=q) | Q(body__icontains=q) 表示标题(title)含有关键词 q 或者正文(body)含有关键词 q ,或逻辑使用 | 符号。如果不用 Q 对象,就只能写成 title__icontains=q, body__icontains=q,这就变成标题(title)含有关键词 q 正文(body)含有关键词 q,就达不到我们想要的目的。

绑定 URL

有了视图函数后记得把视图函数映射到相应了 URL,如下。

blog/urls.py

urlpatterns = [
    # 其他 url 配置
    path('search/', views.search, name='search'),
]

大功告成,在导航栏尝试输入一些关键词,看看效果吧!

当然这样的搜索功能是非常简略的,难以满足一些复杂的搜索需求。编写一个搜索引擎是一个大工程,好在 django-haystack 这款第三方 app 为我们完成了全部工作。使用它我们可以实现更加复杂的搜索功能,比如全文检索、按搜索相关度排序、关键字高亮等等类似于百度搜索的功能,功能十分强大。当然其使用也会复杂一些,下一篇教程将向大家介绍 django-haystack 结合 Elasticsearch 搜索引擎的使用方法。



『讲解开源项目系列』——让对开源项目感兴趣的人不再畏惧、让开源项目的发起者不再孤单。跟着我们的文章,你会发现编程的乐趣、使用和发现参与开源项目如此简单。欢迎留言联系我们、加入我们,让更多人爱上开源、贡献开源~

原文地址:https://www.cnblogs.com/xueweihan/p/12171812.html

时间: 2024-12-07 14:36:25

Django 博客实现简单的全文搜索的相关文章

Django1.9开发博客(10)- 全文搜索

Django本身不提供全文检索的功能,但django-haystack为其提供了全文检索的框架. django-haystack能为Django提供whoosh,solr,Xapian和Elasticsearc四种全文检索引擎作为后端. 其中whoosh为纯python的实现,不是非常大型的应用,是没有问题的. 本文将介绍Django1.9中通过django-haystack与whoosh集成以及whoosh的中文支持. 安装依赖: pip install django-haystackpip

建立django博客应用及数据库模型

1.现在就来创建我们的 Django 博客应用,我把它命名为 blog.激活虚拟环境,进入到 manage.py 文件所在的目录下,运行 python manage.py startapp blog 命令即可建立一个 blog 应用 这个应用的文件夹结构 Django 已经为我们建立好了,但它还只是包含各种文件的一个文件夹而已,Django 目前还不知道这是一个应用.我们得告诉 Django 这是我们建立的应用,专业一点说就是在 Django 的配置文件中注册这个应用.打开 blogprojec

Python Web —— Django博客教程总结

Django博客教程总结 前言_Django博客教程_追梦人物的博客 首先安装virtualenv 安装 pip install virtualenv 创建虚拟环境 Python版本3.5 Django版本1.10.6 pip install Django=1.10.6 原文地址:https://www.cnblogs.com/darksouls/p/8349404.html

关于博客的简单美化

关于博客的简单美化 之前曾经是有过一个基于\(Github\)的博客的,但是代码的操控不是特别熟悉,在就博客里面还发了关于\(Blog\)转移的文章Lomen,但是后来由于某种\(unfortunately\)的原因它挂掉了(我搞了一个星期的博客啊!!!),现在只有一个空荡荡的\(README\)文件挂在上面. 因此短时间内不考虑\(Github\)的博客了,转手进行博客园美化. 博客今本上是照着\(\_rqy\)的"Next"模式依葫芦画瓢的,但是因为\(cnblogs\)的功能并没

Django 博客首页视图

Django 处理 HTTP 请求 Web 应用的交互过程其实就是 HTTP 请求与响应的过程.无论是在 PC 端还是移动端,我们通常使用浏览器来上网,上网流程大致来说是这样的: 我们打开浏览器,在地址栏输入想访问的网址,比如 http://zmrenwu.com/(当然你也可能从收藏夹里直接打开网站,但本质上都是一样的). 浏览器知道我们想要访问哪个网址后,它在后台帮我们做了很多事情.主要就是把我们的访问意图包装成一个 HTTP 请求,发给我们想要访问的网址所对应的服务器.通俗点说就是浏览器帮

Django(博客系统):按照时间分层筛选“/blog/article/?create_time__year=2017”,出现问题:Database returned an invalid datetime value. Are time zone definitions for your database installed?

问题背景 添加文章时间没问题,但为了设定博客文章按照时间分层筛选(创建时间的年份.年月&月份来搜索文章),我在blog这个django app的admin.py的ArticleAdmin类中做了如下设置: date_hierarchy = 'create_time' # 详细时间分层筛选 models.Article中create_time定义如下: create_time = models.DateTimeField(u'创建时间', auto_now_add=True) 设置后,后台呈现效果

Django博客开发-数据建模与样式设定

开发流程介绍 之前Django的学习过程当中已经把基本Django开发学完了,现在以Django 的博客项目完成一遍课程的回顾和总结.同时来一次完整开发的Django体验. 一个产品从研究到编码我们要经历以下的过程: 博客开发需求分析与建模 需求分析 本次项目完成的是一个博客的项目,博客主要目的是为了分享个人的技术,进行技术积累. 主要是发布文章日志.但是也需要有评论和互动.需要完成以下功能点: 1.文章的发布.展示.修改.删除. 2.文章评论 3.读者互动 4.图片管理 概要设计 我们对上面的

在博客中自定义Google代理搜索

直接访问Google可能有些问题,可以利用博客插件,进行代理性质的搜索, 大家试试下面的这个,看看搜索效果如何 Google代理自定义搜索 技术性的知识搜索,还是需要Google的,尤其是外文的资料! ------------------------------------ 

MapReduce 简单的全文搜索2

上一个全文搜索实现了模糊查找,这个主要实现了精确查找,就是比如你查找mapreduce is simple那么他就只查找有这个句子的文章,而不是查找有这三个单词的文章. 这个版本需要重写反向索引,因为需要查找句子,所以需要定位每个单词的在文章中的位置,所以我们的反向索引需要加上单词所在的位置,即我们希望的输出是: MapReduce file1.txt:<1,2,3>;file2.txt:<5,3,1>;这种格式的. 其实这一步比较简单.我们在map的时候输出为 “filename