ルックアップ API リファレンス¶
このドキュメントには、データベースクエリの WHERE
句を構築するための Django API であるルックアップの API リファレンスがあります。ルックアップの 使い方 については クエリを作成する を、新しいルックアップの 作り方 については カスタムのルックアップを書く を参照してください。
ルックアップAPIには2つのコンポーネントがあります。ルックアップを登録する RegisterLookupMixin
クラスと、ルックアップとして登録するためにクラスが実装しなければならないメソッドのセットである クエリ式 API です。
Django には、クエリ式 API に従う 2 つの基本クラスがあり、すべての Django 組み込みルックアップはここから派生しています:
ルックアップ式は3つの部分で構成されています:
フィールド部分(例:
Book.objects.filter(author__best_friends__first_name...
);トランスフォーム(変換)部分(省略可) (
lower__first3chars__reversed
など);ルックアップ部分 (
__icontains
など)。省略した場合のデフォルトは__exact
です。
登録API¶
Django は RegisterLookupMixin
を使って、自分自身やそのインスタンスにルックアップを登録するインターフェイスをクラスに与えます。代表的な例は Field
で、これはすべてのモデルフィールドの基底クラスです。 Transform
もその一つで、これはすべての Django トランスフォームの基底クラスです。
- class lookups.RegisterLookupMixin¶
クラスのルックアップ API を実装するミックスインです。
- 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.lookup_name
が指定された場合はlookup_name
が使用され、指定されなかった場合はlookup.lookup_name
が使用されます。
クラスがルックアップであるためには、 クエリ式 API に従わなければなりません。 Lookup
と Transform
は当然この API に従います。
クエリ式 API¶
クエリ式 API はクラスがクエリ式で使用できるように定義するメソッドの共通セットで、クラス自身を SQL 式に変換します。フィールドの直接参照、集計(Aggregation)、 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 の組み込みバックエンドでは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
リファレンス¶
- class Transform[ソース]¶
Transform
はフィールドの変換を実装するための汎用クラスです。主な例はDateField
をIntegerField
に変換する__year
です。ルックアップ式で
Transform
を使用する場合の表記は<expression>__<transformation>
(例date__year
) です。このクラスは クエリ式 API に従っており、
<expression>__<transform1>__<transform2>
を使用できます。これは Func() 式 に特化したもので、引数を一つだけ受け取ることができます。 また、フィルタの右辺やアノテーションとして直接使用することもできます。- bilateral¶
このトランスフォームを
lhs
とrhs
の両方に適用するかどうかを示すブール値です。両者の変換はrhs
に対して、ルックアップ式に現れる順番で適用されます。デフォルトではFalse
に設定されています。たとえば、 カスタムのルックアップを書く を参照してください。
- lookup_name¶
クエリ式のパース時に使用するルックアップ名です。文字列
"__"
を含むことはできません。
Lookup
リファレンス¶
- class Lookup[ソース]¶
ルックアップ
Lookup
はルックアップを実装するための汎用クラスです。ルックアップは左辺lhs
; 右辺rhs
;lookup_name
を持つクエリ式で、lhs in rhs
やlhs > rhs
のようにlhs
と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))
- rhs¶
右辺 -
lhs
と比較されるもの。これは単なる値であったり、SQL にコンパイルされるものであったり、一般的にはF()
オブジェクトやQuerySet
であったりします。
- lookup_name¶
このルックアップの名前で、クエリ式をパースする際に識別するために使用します。文字列
"__"
を含むことはできません。
- prepare_rhs¶
デフォルトは
True
です。rhs
がプレーンな値の場合、prepare_rhs
はクエリのパラメータとして使用するために、その値を準備するかどうかを決定します。そのために、lhs.output_field.get_prep_value()
が定義されていれば呼び出され、そうでなければrhs
はValue()
でラップされます。
- process_lhs(compiler, connection, lhs=None)[ソース]¶
compiler.compile(lhs)
が返すタプル(lhs_string, lhs_params)
を返します。このメソッドをオーバーライドすることで、lhs
の処理方法を調整できます。compiler
はSQLCompiler
オブジェクトで、lhs
をコンパイルする際にcompiler.compile(lhs)
のように使用します。connection
はベンダ固有の SQL をコンパイルする際に使用します。lhs
がNone
でない場合は、self.lhs
の代わりにlhs
を使用します。
- process_rhs(compiler, connection)[ソース]¶
右辺については
process_lhs()
と同じように扱います。