查找 API 参考 — Django 文档
查找 API 参考
本文档包含查找的 API 参考,即用于构建数据库查询的 WHERE
子句的 Django API。 要了解如何 使用 查找,请参阅 进行查询 ; 要了解如何 创建 新查找,请参阅 自定义查找 。
查找 API 有两个组件:一个 RegisterLookupMixin 类,用于注册查找,以及 Query Expression API,一组类必须实现才能作为查找注册的方法。
Django 有两个基类,它们遵循查询表达式 API 和所有 Django 内置查找的派生源:
一个查找表达式由三部分组成:
- 字段部分(例如
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_name
的 Lookup。 默认实现在所有父类上递归查找,并检查是否有名为lookup_name
的注册查找,返回第一个匹配项。
- get_lookups()
返回映射到 Lookup 类的类中注册的每个查找名称的字典。
- get_transform(transform_name)
返回一个名为
transform_name
的 Transform。 默认实现递归地查看所有父类,以检查是否有任何具有名为transform_name
的注册转换,返回第一个匹配项。
对于要查找的类,它必须遵循 查询表达式 API 。 Lookup 和 Transform 自然遵循这个 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 内置后端的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)
。
- output_field
- 定义
get_lookup()
方法返回的类的类型。 它必须是 Field 实例。
Transform 参考
- class Transform
Transform
是实现字段转换的通用类。 一个突出的例子是__year
,它将DateField
转换为IntegerField
。在查找表达式中使用
Transform
的符号是<expression>__<transformation>
(例如date__year
)。这个类遵循查询表达式API,这意味着您可以使用
<expression>__<transform1>__<transform2>
。 这是一个专门的 Func() 表达式 ,它只接受一个参数。 它也可以用在过滤器的右侧或直接用作注释。- bilateral
一个布尔值,指示此转换是否应同时应用于
lhs
和rhs
。 双边变换将按照它们在查找表达式中出现的相同顺序应用于rhs
。 默认设置为False
。 例如用法,请参见 自定义查找 。
- lhs
左侧 - 正在转换的内容。 它必须遵循 查询表达式 API 。
- lookup_name
查找的名称,用于在解析查询表达式时识别它。 它不能包含字符串
"__"
。
- output_field
定义此转换输出的类。 它必须是 Field 实例。 默认与其
lhs.output_field
相同。
Lookup 参考
- class Lookup
Lookup
是实现查找的通用类。 查找是一个左侧为 lhs 的查询表达式; 右侧,rhs; 和lookup_name
用于在lhs
和rhs
之间进行布尔比较,例如lhs in rhs
或lhs > 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)
一样用于编译lhs
。connection
可用于编译供应商特定的 SQL。 如果lhs
不是None
,则将其用作处理后的lhs
而不是self.lhs
。
- process_rhs(compiler, connection)
右侧的行为方式与 process_lhs() 相同。