查找 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 uses RegisterLookupMixin to give a class the interface to register lookups on itself or its instances. The two prominent examples are Field, the base class of all model fields, and Transform, the base class of all Django transforms.
class lookups.RegisterLookupMixin
一个在类上实现查找 API 的混入。
classmethod
register_lookup
(lookup, lookup_name=None)Registers a new lookup in the class or class instance. For example:
DateField.register_lookup(YearExact)
User._meta.get_field("date_joined").register_lookup(MonthExact)
will register
YearExact
lookup onDateField
andMonthExact
lookup on theUser.date_joined
(you can use Field Access API to retrieve a single field instance). It overrides a lookup that already exists with the same name. Lookups registered on field instances take precedence over the lookups registered on classes.lookup_name
will be used for this lookup if provided, otherwiselookup.lookup_name
will be used.get_lookup
(lookup_name)Returns the Lookup named
lookup_name
registered in the class or class instance depending on what calls it. The default implementation looks recursively on all parent classes and checks if any has a registered lookup namedlookup_name
, returning the first match. Instance lookups would override any class lookups with the samelookup_name
.get_lookups
()Returns a dictionary of each lookup name registered in the class or class instance mapped to the Lookup class.
get_transform
(transform_name)Returns a Transform named
transform_name
registered in the class or class instance. The default implementation looks recursively on all parent classes to check if any has the registered transform namedtransform_name
, returning the first match.
一个类要想成为查找,必须遵循 查询表达式 API。 Lookup 和 Transform 自然遵循这个API。
Changed in Django 4.2:
Support for registering lookups on Field instances was added.
查询表达式 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>
。查询也可以直接在 QuerySet
过滤器中使用:
Book.objects.filter(LessThan(F("word_count"), 7500))
…或注解:
Book.objects.annotate(is_short_story=LessThan(F("word_count"), 7500))
lhs
左手边——被查询的内容。该对象通常遵循 查询表达式 API。它也可以是一个普通的值。
rhs
右侧——
lhs
与什么进行比较。它可以是一个普通的值,也可以是编译成 SQL 的东西,通常是一个F()
对象或一个QuerySet
。lookup_name
这个查询的名称,用于在解析查询表达式时识别它。它不能包含字符串
"__"
。prepare_rhs
Defaults to
True
. When rhs is a plain value, prepare_rhs determines whether it should be prepared for use as a parameter in a query. In order to do so,lhs.output_field.get_prep_value()
is called if defined, orrhs
is wrapped in Value() otherwise.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() 相同。