查找 API 參考
New in Django 1.7.
這篇文檔是查找 API 的參考,Django 用這些API 建構資料庫查詢的
WHERE
子句。若要學習如何使用 查找,參見
執行查詢;若要了解如何建立 新的查找,參見
自定義查找。
查找 API 由兩個部分組成:
RegisterLookupMixin
類,它用于注冊查找;
查詢表達式API,它是一個方法集,類必須實作它們才可以注冊成一個查找。
Django 有兩個類遵循查詢表達式API,且Django 所有内建的查找都繼承自它們:
-
:用于查找一個字段(例如Lookup
中的field_name__exact
)exact
-
:用于轉換一個字段Transform
查找表達式由三部分組成:
- 字段部分(例如,
;Book.objects.filter(author__best_friends__first_name...)
- 轉換部分(可以省略)(例如,
);__lower__first3chars__reversed
- 查找部分(例如,
),如果省略則預設為__icontains
__exact
注冊 API
Django 使用
RegisterLookupMixin
來為類提供接口,注冊它自己的查找。兩個最突出的例子是
Field
(所有模型字段的基類)和
Aggregate
(Django 所有聚合函數的基類)。
class lookups.RegisterLookupMixin
一個mixin,實作一個類上的查找API。
classmethod register_lookup(lookup)
在類中注冊一個新的查找。例如,
DateField.register_lookup(YearExact)
将在
DateField
上注冊一個
YearExact
查找。它會覆寫已存在的同名查找。
get_lookup(lookup_name)
傳回類中注冊的名為
lookup_name
的
Lookup
。預設的實作會遞歸查詢所有的父類,并檢查它們中的任何一個是否具有名稱為
lookup_name
的查找,并傳回第一個比對。
get_transform(transform_name)
傳回一個名為
transform_name
Transform
。預設的實作會遞歸查找所有的父類,并檢查它們中的任何一個是否具有名稱為
transform_name
一個類如果想要成為查找,它必須實作查詢表達式API。
Lookup
和
Transform
一開始就遵循這個API。
查詢表達式API是一個通用的方法集,在查詢表達式中可以使用定義了這些方法的類,來将它們自身轉換為SQL表達式。直接的字段引用,聚合,以及
Transform
類都是遵循這個API的示例。當一個對象實作以下方法時,就被稱為遵循查詢表達式API:
as_sql(self, compiler, connection)
負責從表達式中産生查詢字元串和參數。
compiler
是一個
SQLCompiler
對象,它擁有可以編譯其它表達式的
compile()
方法。
connection
是用于執行查詢的連接配接。
調用
expression.as_sql()
一般是不對的 – 而是應該調用
compiler.compile(expression)
compiler.compile()
方法應該在調用表達式的供應商特定方法時格外小心。
as_vendorname(self, compiler, connection)
as_sql()
的工作方式類似。當一個表達式經過
compiler.compile()
編譯之後, Django會首先嘗試調用
as_vendorname()
,其中
vendorname
是用于執行查詢的後端供應商。對于Django内建的後端,
vendorname
是
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)
output_field
定義
get_lookup()
方法所傳回的類的類型。必須為
Field
的執行個體。
Transform 類參考
class Transform
Transform
是用于實作字段轉換的通用類。一個顯然的例子是
__year
會把
DateField
轉換為
IntegerField
在表達式中執行查找的标記是
Transform<expression>__<transformation>
(例如
date__year
)。
這個類遵循查詢表達式API,也就是說你可以使用
<expression>__<transform1>__<transform2>
bilateral
New in Django 1.8.
一個布爾值,表明是否對
lhs
rhs
都應用這個轉換。如果對兩側都應用轉換,應用在
rhs
的順序和在查找表達式中的出現順序相同。預設這個屬性為
False
。使用方法的執行個體請見自定義查找。
lhs
在左邊,也就是被轉換的東西。必須遵循查詢表達式API。
lookup_name
查找的名稱,用于在解析查詢表達式的時候識别它。
output_field
為這個類定義轉換後的輸出。必須為
Field
的執行個體。預設情況下和
lhs.output_field
相同。
as_sql()
需要被覆寫;否則抛出
NotImplementedError
異常。
get_lookup(lookup_name)
get_lookup()
get_transform(transform_name)
get_transform()
Lookup 類參考
class Lookup
Lookup
是實作查找的通用的類。查找是一個查詢表達式,它的左邊是
lhs
,右邊是
rhs
lookup_name
用于構造
lhs
rhs
之間的比較,來産生布爾值,例如
lhs in rhs
或者
lhs > rhs
<lhs>__<lookup_name>=<rhs>
這個類并不遵循查詢表達式API,因為在它構造的時候出現了
=<rhs>
:查找總是在查找表達式的最後。
lhs
在左邊,也就是被查找的東西。這個對象必須遵循查詢表達式API。
rhs
在右邊,也就是用來和
lhs
比較的東西。它可以是個簡單的值,也可以是在SQL中編譯的一些東西,比如
F()
對象或者
QuerySet
lookup_name
process_lhs(compiler, connection[, lhs=None])
傳回元組
(lhs_string, lhs_params)
,和
compiler.compile(lhs)
所傳回的一樣。這個方法可以被覆寫,來調整
lhs
的處理方式。
compiler
SQLCompiler
對象,可以像
compiler.compile(lhs)
這樣使用來編譯
lhs
connection
可以用于編譯供應商特定的SQL語句。
lhs
如果不為
None
, 會代替
self.lhs
作為處理後的
lhs
使用。
process_rhs(compiler, connection)
對于右邊的東西,和
process_lhs()
的行為相同。
譯者: Django 文檔協作翻譯小組 ,原文: Lookup expressions 本文以 CC BY-NC-SA 3.0 協定釋出,轉載請保留作者署名和文章出處。 人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。