Django 博客实现简单全文搜索功能详解

陆景行
陆景行
发布时间:2026-10-13| 7人浏览过
原创

本文介绍如何在 Django 博客中实现简单的全文搜索功能。通过构建 HTML 搜索表单,利用 request.GET 获取关键词,并结合 Django 的 Q 对象实现标题与正文的“或”逻辑查询。文章详细讲解了视图函数的编写、URL 映射及错误处理,为后续集成 django-haystack 和 Elasticsearch 打下基础。

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

第一步是让用户能够输入搜索关键词,因此我们需要在博客前端提供一个搜索表单。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 属性。当用户在此输入框中输入内容并提交表单时,输入的数据将以键值对的形式发送至服务器,键名由 name 属性指定。这样,服务器即可通过该键名获取用户输入的内容。

当用户输入关键词并点击搜索按钮后,数据被发送至 Django 后台服务器。表单的 action 属性设置为 {% url 'blog:search' %}(尽管该视图函数尚未创建),这意味着提交的数据将被发送至 blog 应用下名为 search 的视图函数所对应的 URL。

实现搜索视图与 Q 对象查询

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

搜索功能将由 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,则变为标题包含 q 且正文也包含 q 的“与”逻辑,这不符合我们期望的搜索目的。

URL 映射与功能测试

绑定 URL

创建好视图函数后,需将其映射到相应的 URL,配置如下:

blog/urls.py


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

至此功能完成,请在导航栏尝试输入关键词,查看效果!

进阶:集成 django-haystack 与 Elasticsearch

当然,这种搜索功能较为简略,难以满足复杂的搜索需求。构建一个完整的搜索引擎是一项庞大工程,幸运的是 django-haystack 这款第三方应用已为我们完成了大部分工作。使用它可实现更复杂的搜索功能,如全文检索、按相关度排序、关键字高亮等类似百度搜索的功能,虽然使用复杂度有所增加,但功能十分强大。在下一篇教程中,我们将介绍如何结合 django-haystack 与 Elasticsearch 搜索引擎使用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。