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