Django的Lookup API用于构建数据库查询的 WHERE 子句. 如何 使用 Lookup请参见 执行查询;
自定义Lookup请参见 Custom Lookups.
Lookup API 由两部分组成: 一是 RegisterLookupMixin 类用于注册lookup,
二是 查找表达式接口, 是普通类要注册为lookup必须要要实现的一组方法.
Django有两个查找表达式的基类, Django所有的内置查找都继承自它们:
一个查找表达式由三部分组成:
Book.objects.filter(author__best_friends__first_name...);__lower__first3chars__reversed);__icontains) 如果没有则默认为 __exact.Django通过 RegisterLookupMixin 来给类提供注册查找的接口. 两个明显的例子:
Field 所有模型字段的基类 和
Aggregate 所有聚合函数的基类.
lookups.RegisterLookupMixin¶用于给类”混入”查找API.
register_lookup(lookup, lookup_name=None)¶给类注册一个查找. 例如
DateField.register_lookup(YearExact) 会将 YearExact 查找注册到 DateField.
如果已存在相同名字查找则会覆盖原查找. 如果传入了 lookup_name 将会使用其作为查找名,
否则使用 lookup.lookup_name.
新增 lookup_name 参数.
查询表达式接口是用于将查找转换成SQL查询的一组公共方法.
直接的字段引用, 聚合, 以及 Transform 类都遵循了这个接口, 遵循查询表达式接口需要实现以下接口:
as_sql(self, compiler, connection)¶负责生成查询字符串和参数.
compiler 是 SQLCompiler 对象, 它具有一个 compile() 方法可以编译其他的表达式.
connection 是用于执行查询的连接.
直接调用 expression.as_sql() 是错误的, 应该使用 compiler.compile(expression),
compiler.compile() 才会去调用对应的数据库方法.
如果 as_vendorname() 方法或子类传入数据来覆盖SQL字符串的生成,
可以在这个方法上传入自定义关键字参数. 详见 Func.as_sql().
as_vendorname(self, compiler, connection)¶作用类似 as_sql(). 当表达式被
compiler.compile() 编译后, Django会首先调用 as_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 参考¶Transform¶Transform 是实现字段转换的通用类. 一个常用的例子 __year 将 DateField 转换成 IntegerField.
在查找表达式中 Transform 的用法是
<expression>__<transformation> (例如. date__year).
该类遵循 查询表达式接口, 因此可以使用 <expression>__<transform1>__<transform2>.
它是一个特殊的 Func()表达式 , 只接收一个参数.
它可以用于右侧过滤或者直接作为注解使用.
Transform 作为 Func 子类.
bilateral¶布尔值, 表示该转换是否适用于 lhs 和 rhs. 双边转换将按照查找表达式中出现的顺序应用于 rhs .
默认值为 False. 使用方法见: Custom Lookups.
lookup_name¶查找的名字, 用于在解析查询表达式时识别. 不包含 "__".
Lookup 参考¶Lookup¶Lookup 是实现查找的通用类. 一个查询表达式是由左侧 lhs, 右侧,
rhs 和 lookup_name 组成, 用于在 lhs 和 rhs 之间比较返回布尔值, 例如 lhs in rhs 和
lhs > rhs.
在表达式中的使用方式是: <lhs>__<lookup_name>=<rhs>.
该类并不遵循 查询表达式接口,
因此像上面的 =<rhs> 必须在查询表达式最后.
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() 同样的方式处理右侧.
10月 29, 2021