查找 API 参考 — Django 文档

来自菜鸟教程
Django/docs/3.0.x/ref/models/lookups
跳转至:导航、​搜索

查找 API 参考

本文档包含查找的 API 参考,即用于构建数据库查询的 WHERE 子句的 Django API。 要了解如何 使用 查找,请参阅 进行查询 ; 要了解如何 创建 新查找,请参阅 自定义查找

查找 API 有两个组件:一个 RegisterLookupMixin 类,用于注册查找,以及 Query Expression API,一组类必须实现才能作为查找注册的方法。

Django 有两个基类,它们遵循查询表达式 API 和所有 Django 内置查找的派生源:

  • Lookup:查找字段(例如 field_name__exactexact)
  • Transform:变换一个字段

一个查找表达式由三部分组成:

  • 字段部分(例如 Book.objects.filter(author__best_friends__first_name...);
  • 转换部分(可以省略)(例如 __lower__first3chars__reversed);
  • 查找(例如 __icontains),如果省略,则默认为 __exact

注册接口

Django 使用 RegisterLookupMixin 为类提供接口以在其自身上注册查找。 两个突出的例子是 Field,所有模型字段的基类,和 Transform,所有 Django 转换的基类。

class lookups.RegisterLookupMixin

在类上实现查找 API 的 mixin。

classmethod register_lookup(lookup, lookup_name=None)

在类中注册一个新的查找。 例如,DateField.register_lookup(YearExact) 将在 DateField 上注册 YearExact 查找。 它会覆盖已存在的同名查找。 lookup_name 将用于此查找(如果提供),否则将使用 lookup.lookup_name

get_lookup(lookup_name)

返回在类中注册的名为 lookup_nameLookup。 默认实现在所有父类上递归查找,并检查是否有名为 lookup_name 的注册查找,返回第一个匹配项。

get_lookups()

返回映射到 Lookup 类的类中注册的每个查找名称的字典。

get_transform(transform_name)

返回一个名为 transform_nameTransform。 默认实现递归地查看所有父类,以检查是否有任何具有名为 transform_name 的注册转换,返回第一个匹配项。

对于要查找的类,它必须遵循 查询表达式 APILookupTransform 自然遵循这个 API。


查询表达式 API

查询表达式 API 是一组通用的方法,类定义为可在查询表达式中使用以将自身转换为 SQL 表达式。 直接字段引用、聚合和 Transform 是遵循此 API 的示例。 一个类在实现以下方法时被称为遵循查询表达式 API:

as_sql(compiler, connection)

为表达式生成 SQL 片段。 返回一个元组 (sql, params),其中 sql 是 SQL 字符串,params 是查询参数的列表或元组。 compiler 是一个 SQLCompiler 对象,它有一个 compile() 方法,可以用来编译其他表达式。 connection 是用于执行查询的连接。

调用 expression.as_sql() 通常是不正确的 - 而应该使用 compiler.compile(expression)compiler.compile() 方法将负责调用特定于供应商的表达式方法。

如果 as_vendorname() 方法或子类可能需要提供数据来覆盖 SQL 字符串的生成,则可以在此方法上定义自定义关键字参数。 有关用法示例,请参阅 Func.as_sql()

as_vendorname(compiler, connection)
as_sql() 方法一样工作。 当 compiler.compile() 编译表达式时,Django 将首先尝试调用 as_vendorname(),其中 vendorname 是用于执行查询的后端的供应商名称。 vendorname 是 Django 内置后端的 postgresqloraclesqlitemysql 之一。
get_lookup(lookup_name)
必须返回名为 lookup_name 的查找。 例如,通过返回 self.output_field.get_lookup(lookup_name)
get_transform(transform_name)
必须返回名为 transform_name 的查找。 例如,通过返回 self.output_field.get_transform(transform_name)
output_field
定义 get_lookup() 方法返回的类的类型。 它必须是 Field 实例。


Transform 参考

class Transform

Transform 是实现字段转换的通用类。 一个突出的例子是 __year,它将 DateField 转换为 IntegerField

在查找表达式中使用 Transform 的符号是 <expression>__<transformation>(例如 date__year)。

这个类遵循查询表达式API,这意味着您可以使用<expression>__<transform1>__<transform2>。 这是一个专门的 Func() 表达式 ,它只接受一个参数。 它也可以用在过滤器的右侧或直接用作注释。

bilateral

一个布尔值,指示此转换是否应同时应用于 lhsrhs。 双边变换将按照它们在查找表达式中出现的相同顺序应用于 rhs。 默认设置为 False。 例如用法,请参见 自定义查找

lhs

左侧 - 正在转换的内容。 它必须遵循 查询表达式 API

lookup_name

查找的名称,用于在解析查询表达式时识别它。 它不能包含字符串 "__"

output_field

定义此转换输出的类。 它必须是 Field 实例。 默认与其lhs.output_field相同。


Lookup 参考

class Lookup

Lookup 是实现查找的通用类。 查找是一个左侧为 lhs 的查询表达式; 右侧,rhs; 和 lookup_name 用于在 lhsrhs 之间进行布尔比较,例如 lhs in rhslhs > rhs

在表达式中使用查找的符号是 <lhs>__<lookup_name>=<rhs>

此类不遵循 查询表达式 API,因为它的构造中有 =<rhs>:查找始终是查找表达式的结尾。

lhs

左侧 - 正在查找的内容。 该对象必须遵循 查询表达式 API

rhs

右侧 - lhs 与什么进行比较。 它可以是一个普通值,也可以是编译成 SQL 的东西,通常是一个 F() 对象或一个 QuerySet

lookup_name

此查找的名称,用于在解析查询表达式时识别它。 它不能包含字符串 "__"

process_lhs(compiler, connection, lhs=None)

返回一个元组 (lhs_string, lhs_params),由 compiler.compile(lhs) 返回。 可以重写此方法以调整 lhs 的处理方式。

compiler 是一个 SQLCompiler 对象,与 compiler.compile(lhs) 一样用于编译 lhsconnection 可用于编译供应商特定的 SQL。 如果lhs不是None,则将其用作处理后的lhs而不是self.lhs

process_rhs(compiler, connection)

右侧的行为方式与 process_lhs() 相同。