查找 API 参考

本文档包含查找的 API 参考,Django API 用于构建数据库查询的WHERE子句。要了解如何使用查找,请参阅执行查询;要了解如何创建新的查找,请参阅如何编写自定义查找

查找 API 包含两个组件:一个RegisterLookupMixin类,用于注册查找,以及查询表达式 API,这是一组类必须实现才能注册为查找的方法。

Django 有两个遵循查询表达式 API 的基类,所有 Django 内置查找都源自这些基类。

  • Lookup:查找字段(例如field_name__exactexact

  • Transform:转换字段

查找表达式由三个部分组成

  • 字段部分(例如 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

get_lookup(lookup_name)

返回在类或类实例中注册的名称为lookup_nameLookup,具体取决于调用它的对象。默认实现会递归查找所有父类,并检查是否有任何父类注册了名为lookup_name的查找,并返回第一个匹配项。实例查找将覆盖任何具有相同lookup_name的类查找。

get_lookups()

返回一个字典,其中每个在类或类实例中注册的查找名称都映射到Lookup类。

get_transform(transform_name)

返回在类或类实例中注册的名称为transform_nameTransform。默认实现会递归查找所有父类,以检查是否有任何父类注册了名为transform_name的转换,并返回第一个匹配项。

要使一个类成为查找,它必须遵循查询表达式 APILookupTransform自然遵循此 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 的内置后端是postgresqloraclesqlitemysql之一。

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[source]

Transform是一个实现字段转换的通用类。一个突出的例子是__year,它将DateField转换为IntegerField

在查找表达式中使用Transform的表示法是<expression>__<transformation>(例如date__year)。

此类遵循查询表达式API,这意味着您可以使用<expression>__<transform1>__<transform2>。它是一个专门的Func()表达式,只接受一个参数。它也可以用在过滤器的右侧或直接用作注释。

bilateral

一个布尔值,指示此转换是否应同时应用于lhsrhs。双边转换将按它们在查找表达式中出现的顺序应用于rhs。默认设置为False。有关用法示例,请参阅如何编写自定义查找

lhs[source]

左侧 - 正在转换的内容。它必须遵循查询表达式API

lookup_name

查找的名称,用于在解析查询表达式时识别它。它不能包含字符串"__"

output_field

定义此转换输出的类。它必须是Field实例。默认为与其lhs.output_field相同。

Lookup 参考

class Lookup[source]

Lookup是一个实现查找的通用类。查找是一个具有左侧lhs、右侧rhslookup_name的查询表达式,用于在lhsrhs之间生成布尔比较,例如lhs in rhslhs > 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

默认为Truerhs为普通值时,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)来编译lhsconnection可用于编译特定于供应商的SQL。如果lhs不是None,则使用它作为处理后的lhs,而不是self.lhs

process_rhs(compiler, connection)[source]

对右侧的行为方式与process_lhs()相同。

返回顶部