查找 API 参考¶
本文档提供了查找的 API 参考,它是 Django 的 API,用于构建数据库查询的 WHERE
子句。要学习如何 使用 查找,请看 执行查询;要学习如何 创建 新的查找,请看 自定义查询器。
查找 API 有两个组成部分:一个是 RegisterLookupMixin
类,用于注册查找;另一个是 查询表达式 API,一个类要想注册为查找,必须实现一组方法。
Django 有两个遵循查询表达式 API 的基类,所有 Django 内置的查找都是从这里派生出来的。
一个查找表达式由三部分组成:
- 字段部分(如
Book.objects.filter(author__best_friends__first_name...
); - 转换部分(可省略)(如
__lower__first3chars__reversed
); - 查找(例如
__icontains
),如果省略,默认为__exact
。
注册 API¶
Django 使用 RegisterLookupMixin
来给一个类提供对自己进行注册查找的接口。两个突出的例子是 Field
,所有模型字段的基类,以及 Transform
,所有 Django 变换的基类。
-
class
lookups.
RegisterLookupMixin
¶ 一个在类上实现查找 API 的混入。
-
classmethod
register_lookup
(lookup, lookup_name=None)¶ 在类中注册一个新的查找。例如
DateField.register_lookup(YearExact)
将在DateField
上注册YearExact
的查找。它将覆盖已经存在的同名查找。如果提供了lookup_name
将被用于这个查找,否则lookup.lookup_name
将被使用。
-
get_lookup
(lookup_name)¶ 返回在类中注册的名为
lookup_name
的Lookup
。默认的实现是递归地查找所有父类,并检查是否有名为lookup_name
的注册查找,返回第一个匹配的类。
-
get_transform
(transform_name)¶ 返回一个名为
transform_name
的transform
。缺省的实现是递归地查找所有父类,检查是否有名为transform_name
的注册变换,返回第一个匹配的类。
-
classmethod
查询表达式 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 内置后端的postgresql
、oracle
、sqlite
、mysql
中的一个。
-
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)
。
Transform
参考¶
-
class
Transform
¶ Transform
是一个实现字段转换的通用类。一个突出的例子是__year
,它将DateField
转变为IntegerField
。在查询表达式中使用
Transform
的符号是<expression>__<transformation>
(例如date__year
)。这个类遵循 查询表达式 API,这意味着你可以使用
<expression>__<transform1>__<transform2>
。它是一个专门的 Func() 表达式,只接受一个参数。 它也可以用在过滤器的右侧,或者直接作为注解使用。-
bilateral
¶ 一个布尔值,表示这一转换是否应适用于
lhs
和rhs
。双边转换将按照查找表达式中出现的顺序应用于rhs
。默认情况下,它被设置为False
。关于用法示例,请参见 自定义查询器。
-
lookup_name
¶ 查找的名称,用于在解析查询表达式时识别它。它不能包含字符串
"__"
。
-
Lookup
参考¶
-
class
Lookup
¶ Lookup
是一个实现查找的通用类。一个查找是一个查询表达式,它的左侧是lhs
;右侧是rhs
;还有一个lookup_name
,用于在lhs
和rhs
之间进行布尔比较,例如lhs in rhs
或lhs > rhs
。在表达式中使用查找的符号是
<lhs>__<lookup_name>=<rhs>
。这个类的作用是查询表达式,但是,由于它的构造上有
=<rhs>
,所以,查找必须始终是查找表达式的结尾。-
rhs
¶ 右侧——
lhs
与什么进行比较。它可以是一个普通的值,也可以是编译成 SQL 的东西,通常是一个F()
对象或一个QuerySet
。
-
lookup_name
¶ 这个查询的名称,用于在解析查询表达式时识别它。它不能包含字符串
"__"
。
-
process_lhs
(compiler, connection, lhs=None)¶ 返回由
compiler.compile(lhs)
返回的元组(lhs_string, lhs_params)
。这个方法可以被重写来调整lhs
的处理方式。compiler
是一个SQLCompiler
对象,可以像compiler.compile(lhs)
一样用来编译lhs
。connection
可以用于编译厂商特定的 SQL。如果lhs
不是None
,就用它作为处理后的lhs
代替self.lhs
。
-
process_rhs
(compiler, connection)¶ 右侧的行为与
process_lhs()
相同。
-