Skip to content

djangodocs

Django 4.1
  • 6.1 current
  • 6.0
  • 5.2 LTS
  • 5.1 unsupported
  • 5.0 unsupported
  • 4.2 unsupported
  • 4.1 unsupported
  • 4.0 unsupported
  • 3.2 unsupported
  • 3.1 unsupported
  • 3.0 unsupported
  • 2.2 unsupported
  • 2.1 unsupported
  • 2.0 unsupported
简体中文
  • English
  • 简体中文
  • Français
  • 日本語
  • Bahasa Indonesia
  • Italiano
  • Português (Brasil)
  • 한국어
  • Español
  • Ελληνικά
  • Polski
Documentation contents
  • Django 文档
  • 开始
  • 使用 Django
    • 如何安装 Django
    • 模型和数据库
      • 模型
      • 执行查询
      • 聚合
      • 搜索
      • 管理器
      • 执行原生 SQL 查询
      • 数据库事务
      • 多数据库
      • 表空间(Tablespaces)
      • 数据库访问优化
      • 数据库工具
      • 模型关联 API 用法示例
    • 处理 HTTP 请求
    • 使用表单
    • 模板
    • 基于类的视图
    • 迁移
    • 管理文件
    • Django 中的测试
    • Django中的用户认证
    • Django 缓存框架
    • 条件视图处理
    • 加密签名
    • 发送邮件
    • 国际化和本地化
    • 日志
    • 分页
    • Django 的安全性
    • 性能和优化
    • 序列化 Django 对象
    • Django 配置
    • 信号
    • 系统检查框架
    • 扩展包
    • 异步支持
  • 操作指南
  • Django FAQ
  • API 参考
  • 元文件和杂记
  • 术语
  • 发行说明
  • Django internals
Django 4.1 is no longer supported. It receives no security fixes. Use it for reference only. Latest release
Chinese (Simplified) translation. Contributed by the Django community. 73.8% Help translate
  1. Django 4.1
  2. 使用 Django
  3. 模型和数据库

搜索Link to this heading#

Web 应用的常见任务是根据用户输入查出数据库中的数据。在一个简单例子中,会是通过分类筛选一个对象列表。一个更复杂的用例可能会要求根据重量,分类,多语言等筛选对象。本文介绍了一些常见用例和你能使用的工具。

我们会引用与 执行查询 中一样的模型。

用例Link to this heading#

标准文本查询Link to this heading#

文本字段能通过匹配运算进行筛选。例如,你可能会这样查找一个作者:

Code
>>> Author.objects.filter(name__contains='Terry')
[<Author: Terry Gilliam>, <Author: Terry Jones>]

这是一种非常简陋的方案,因为它要求用户必须知道用户名中包含的字符串。大小写不敏感的匹配 (icontains) 不失为一种更好的方案,但优化的程度有限。

一个更高级的数据库比较函数Link to this heading#

若你使用的是 PostgreSQL,Django 提供了 数据特殊筛选工具 帮助你巧妙利用更复杂的查询条件。其它数据库也有不同的筛选工具,可能是通过插件或用户自定义函数实现的。Django 此时还没有为他们提供任何支持。我们会用来自 PostgreSQL 的实例来证明其包含的功能函数。

在其它数据库中搜索

所有由 django.contrib.postgres 提供的筛选工具均基于 自定义查询 和 数据库函数 实现。根据你使用的数据库,你应该构建响应的查询,实现类似的 API。若有某个东西无法以这种方式实现,请新建一个工单。

在上面的例子中,我们可以确认大小写不敏感的查询会更实用一些。当处理英文以外的名字时,可以用 无重音比较 来优化:

Code
>>> Author.objects.filter(name__unaccent__icontains='Helen')
[<Author: Helen Mirren>, <Author: Helena Bonham Carter>, <Author: Hélène Joy>]

这展开了另一个关于通过名字的不同拼写进行比较的讨论。但这种比较是不对称的 —— 筛选 Helen 能拿到 Helena 或 Hélène,但反着来却不行。还有一个选项允许使用 trigram_similar 比较,这回比较字母的序列。

例如:

Code
>>> Author.objects.filter(name__unaccent__lower__trigram_similar='Hélène')
[<Author: Helen Mirren>, <Author: Hélène Joy>]

现在还有一个问题 —— 名字 "Helena Bonham Carter" 有点太长了,以至于没有显示。三元搜索综合考虑了三种字母的所有组合形式,并同时再查询和源字符串中比较了出现的次数。对于长名字,源字符串中包含了更多的组合方式,所以其不再被认为是一种近似匹配。

要基于你提供的特定数据集合选择一个合适的比较函数,例如依据使用的语言和待搜索的文本。我们见过的所有例子都是关于短字符串的,这使得用户可以输入与源数据关联较大(根据不同的定义)的内容。

文档搜索Link to this heading#

标准数据库操作对于大量文本搜索来说太过简陋了。虽然上面的示例可以看作是对字符串的操作,但是全文搜索查看的是实际的单词。依据所使用的系统,可以采用下面的某些方法:

  • 忽略 “停止单词”,例如 "a","the","and"。

  • 词干化,这样 "pony" 和 "ponies" 会被认为是一样的。

  • 根据不同的标准为单词设置权重,例如其在文本中出现的频率,或所属字段(如标题或关键字)的重要性。

使用搜索软件有很多选项,最常见的有 Elastic 和 Solr。它们都是基于全文搜索的解决方案。要用它们搜索来自 Django 模型的数据,你需要一个抽象层,将数据(包括对数据库 id 的指针)转换为文本文档。当使用该引擎的某次搜索返回了一份文档,你可以在数据库中查看它。有很多第三方库被设计为处理这种问题。

PostgreSQL 支持Link to this heading#

PostgreSQL 内置了其专属的全文本搜索实现。虽然并不像其它搜索引擎那样强大,但它的优点是内置在数据库中,所以它能很方便的与其它关联查询条件进行联合查询,如按分类查询。

django.contrib.postgres 模块提供了一些助手函数来执行这些查询。例如,查询可能筛选出所有提到了 "cheese" 的博客条目:

Code
>>> Entry.objects.filter(body_text__search='cheese')
[<Entry: Cheese on Toast recipes>, <Entry: Pizza recipes>]

你也可以在联合字段或关联模型上进行筛选:

Code
>>> Entry.objects.annotate(
...     search=SearchVector('blog__tagline', 'body_text'),
... ).filter(search='cheese')
[
    <Entry: Cheese on Toast recipes>,
    <Entry: Pizza Recipes>,
    <Entry: Dairy farming in Argentina>,
]

参阅 contrib.postgres 全文搜索 文档获取全部细节。

This page as Markdown JSON

Edit this page on GitHub Official version

Previous聚合 Next管理器

On this page

  • 用例
    • 标准文本查询
    • 一个更高级的数据库比较函数
    • 文档搜索
      • PostgreSQL 支持

An unofficial rendering of the Django documentation.

Not affiliated with or endorsed by the Django Software Foundation. The documentation is copyright © Django Software Foundation and individual contributors, and is used under the BSD 3-Clause licence. “Django” is a trademark of the Django Software Foundation.

This translation is the work of the Django i18n community, not of this site. Read the official documentation at docs.djangoproject.com.

👋 Jason Cartwright