查找 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 的 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
。
查询表达式 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[source]¶
Transform
是一个实现字段转换的通用类。一个突出的例子是__year
,它将DateField
转换为IntegerField
。在查找表达式中使用
Transform
的表示法是<expression>__<transformation>
(例如date__year
)。此类遵循查询表达式API,这意味着您可以使用
<expression>__<transform1>__<transform2>
。它是一个专门的Func()表达式,只接受一个参数。它也可以用在过滤器的右侧或直接用作注释。- lookup_name¶
查找的名称,用于在解析查询表达式时识别它。它不能包含字符串
"__"
。
Lookup
参考¶
- class Lookup[source]¶
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)[source]¶
返回一个元组
(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)[source]¶
对右侧的行为方式与
process_lhs()
相同。