查找 API 参考¶
本文档包含查找的 API 参考,即 Django 用于构建数据库查询 WHERE
子句的 API。要了解如何使用查找,请参阅 执行查询;要了解如何创建新的查找,请参阅 如何编写自定义查找。
查找 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 的 mixin。
-
classmethod
register_lookup
(lookup, lookup_name=None)¶ 在类或类实例中注册新的查找。例如
DateField.register_lookup(YearExact) User._meta.get_field("date_joined").register_lookup(MonthExact)
将在
DateField
上注册YearExact
查找,并在User.date_joined
上注册MonthExact
查找(可以使用 字段访问 API 来检索单个字段实例)。它会覆盖已存在且名称相同的查找。在字段实例上注册的查找优先于在类上注册的查找。如果提供了lookup_name
,则将使用它作为此查找的名称,否则将使用lookup.lookup_name
。
-
classmethod
要使一个类成为查找,它必须遵循 查询表达式 API。 Lookup
和 Transform
自然地遵循此 API。
添加了对在 Field
实例上注册查找的支持。
查询表达式 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>
。查找也可以直接在QuerySet
过滤器中使用Book.objects.filter(LessThan(F("word_count"), 7500))
…或注释
Book.objects.annotate(is_short_story=LessThan(F("word_count"), 7500))
-
rhs
¶ 右侧 -
lhs
正在与之比较的内容。它可以是一个普通值,也可以是编译成 SQL 的东西,通常是F()
对象或QuerySet
。
-
lookup_name
¶ 此查找的名称,用于在解析查询表达式时识别它。它不能包含字符串
"__"
。
-
prepare_rhs
¶ 默认为
True
。当rhs
是一个普通值时,prepare_rhs
决定是否应该将其准备为查询中的参数。为了做到这一点,如果定义了lhs.output_field.get_prep_value()
,则调用它,否则将rhs
包裹在Value()
中。
-
process_lhs
(compiler, connection, lhs=None)¶ 返回一个元组
(lhs_string, lhs_params)
,如compiler.compile(lhs)
所返回。此方法可以被重写以调整lhs
的处理方式。compiler
是一个SQLCompiler
对象,用于像compiler.compile(lhs)
一样编译lhs
。connection
可用于编译特定于供应商的 SQL。如果lhs
不是None
,请将其用作处理后的lhs
,而不是self.lhs
。
-
process_rhs
(compiler, connection)¶ 行为与
process_lhs()
相同,用于右侧。
-