本文档包含查找的API引用,用于构建 WHERE 数据库查询的子句。学会如何 use 查找,见 进行查询 ;学习如何 创造 新查找,请参见 如何编写自定义查找 .
查找API有两个组件:A 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变换的基类。
在类上实现查找API的混合。
在类或类实例中注册新查找。例如::
DateField.register_lookup(YearExact)
User._meta.get_field("date_joined").register_lookup(MonthExact)
将注册 YearExact 查找上 DateField 和 MonthExact 在网上查找 User.date_joined (您可以使用 Field Access API 以检索单个字段实例)。它将覆盖已存在的同名查找。在字段实例上注册的查找优先于在类上注册的查找。 lookup_name 将用于此查找(如果提供),否则为 lookup.lookup_name 将会被使用。
要使类成为查找,它必须遵循 Query Expression API . Lookup 和 Transform 当然要遵循这个API。
查询表达式API是一组常见的方法,类将这些方法定义为可在查询表达式中使用,以便将它们自己转换为SQL表达式。直接字段引用、聚合和 Transform 是遵循此API的示例。当类实现以下方法时,称其遵循查询表达式API:
生成该运算式的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_sql() 方法。当表达式由编译时 compiler.compile() ,Django将首先尝试调用 as_vendorname() 在哪里 vendorname 是用于执行查询的后端的供应商名称。这个 vendorname 是其中之一 postgresql , oracle , sqlite 或 mysql 用于Django的内置后端。
必须返回名为的查找 lookup_name . 例如,通过返回 self.output_field.get_lookup(lookup_name) .
必须返回名为的查找 transform_name . 例如,通过返回 self.output_field.get_transform(transform_name) .
Transform 参考¶A Transform 是用于实现字段转换的泛型类。一个突出的例子是 __year 它改变了 DateField 变成一个 IntegerField .
使用的符号 Transform 在查找公式中是 <expression>__<transformation> (例如: date__year )。
本课程遵循 Query Expression API ,这意味着您可以使用 <expression>__<transform1>__<transform2> . 这是一个专门的 Func() expression 只接受一个论点。它也可以在过滤器的右侧使用,或者直接用作注释。
一个布尔值,指示此转换是否应同时应用于 lhs 和 rhs . 双边转变将适用于 rhs 与它们在查找表达式中的显示顺序相同。默认设置为 False . 例如用法,请参见 如何编写自定义查找 .
左手边——正在改变的东西。它必须跟随 Query Expression API .
查找的名称,用于在分析查询表达式时对其进行标识。它不能包含字符串 "__" .
Lookup 参考¶A 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))
左手边--正在查找的内容。该对象通常跟随在 Query Expression API 。它也可能是一个普通的价值。
右手边-什么 lhs 正在与进行比较。它可以是一个普通值,也可以是编译成SQL的值,通常是 F() 对象或 QuerySet .
此查找的名称,用于在分析查询表达式时标识它。它不能包含字符串 "__" .
默认为 True 。什么时候 rhs 是一个简单的值, prepare_rhs 确定是否应准备将其用作查询中的参数。为了做到这一点, lhs.output_field.get_prep_value() 如果已定义,则调用,或者 rhs 被包裹在 Value() 否则的话。
返回元组 (lhs_string, lhs_params) ,由返回 compiler.compile(lhs) . 可以重写此方法以优化 lhs 进行处理。
compiler 是一个 SQLCompiler 对象,用作 compiler.compile(lhs) 编译用 lhs . 这个 connection 可用于编译特定于供应商的SQL。如果 lhs 不是 None ,将其用作已处理的 lhs 而不是 self.lhs .
行为方式与 process_lhs() ,右侧。
5月 28, 2025