查找 API 参考

    查找 API 有两个组成部分:一个是 RegisterLookupMixin 类,用于注册查找;另一个是 ,一个类要想注册为查找,必须实现一组方法。

    Django 有两个遵循查询表达式 API 的基类,所有 Django 内置的查找都是从这里派生出来的。

    • Lookup:查找一个字段(例如 field_name__exactexact
    • :转换一个字段

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

    • 字段部分(如 Book.objects.filter(author__best_friends__first_name...);
    • 查找(例如 __icontains),如果省略,默认为 __exact

    Django 使用 RegisterLookupMixin 来给一个类提供对自己进行注册查找的接口。两个突出的例子是 ,所有模型字段的基类,以及 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_name 的注册查找,返回第一个匹配的类。

    • get_lookups()

      返回映射到 Lookup 类的类中注册的每个查找名称的字典。

    • get_transform(transform_name)

      返回一个名为 transform_nametransform。缺省的实现是递归地查找所有父类,检查是否有名为 transform_name 的注册变换,返回第一个匹配的类。

    一个类要想成为查找,必须遵循 。 Lookup 和 自然遵循这个API。

    查询表达式 API 是一组通用的方法,这些方法被定义为可用于查询表达式,将自己翻译成 SQL 表达式。直接字段引用、聚合和 Transform 是遵循这个 API 的例子。当一个类实现了以下方法时,就可以说它遵循了查询表达式 API:

    as_sql(compiler, connection)

    生成表达式的 SQL 片段。返回一个元组 (sql, params),其中 sql 是 SQL 字符串,params 是查询参数的列表或元组。compiler 是一个 SQLCompiler 对象,它有一个 compile() 方法,可以用来编译其他表达式。connection 是用于执行查询的连接。

    如果 方法或子类很可能需要提供数据来覆盖 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() 方法返回的类的类型。它必须是一个 实例。

    class Transform

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

    在查询表达式中使用 Transform 的符号是 <expression>__<transformation> (例如 date__year)。

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

    • bilateral

      一个布尔值,表示这一转换是否应适用于 lhsrhs。双边转换将按照查找表达式中出现的顺序应用于 rhs。默认情况下,它被设置为 False。关于用法示例,请参见 How to write custom lookups

    • lhs

      左侧——正在转换的内容。它必须遵循 。

    • output_field

      定义这个转换输出的类。它必须是一个 Field 实例。默认情况下是与其 lhs.output_field 相同。

    class Lookup

    Lookup 是一个实现查找的通用类。一个查找是一个查询表达式,它的左侧是 ;右侧是 rhs;还有一个 lookup_name,用于在 lhsrhs 之间进行布尔比较,例如 lhs in rhslhs > rhs

    The primary notation to use a lookup in an expression is <lhs>__<lookup_name>=<rhs>. Lookups can also be used directly in QuerySet filters:

    …or annotations:

    1. Book.objects.annotate(is_short_story=LessThan(F('word_count'), 7500))
    • lhs

      The left-hand side - what is being looked up. The object typically follows the . It may also be a plain value.

    • 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) 一样用来编译 lhsconnection 可以用于编译厂商特定的 SQL。如果 lhs 不是 None,就用它作为处理后的 lhs 代替 self.lhs

    • process_rhs(compiler, connection)

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

    Changed in Django 4.0: