查找 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>。查询也可以直接在- 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¶
- 这个查询的名称,用于在解析查询表达式时识别它。它不能包含字符串 - "__"。
 - 
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()相同。
 Changed in Django 4.0:- 增加了对在 - QuerySet注解、聚合和直接在过滤器中使用查找的支持。
- 
 
          