このドキュメントには、データベースクエリの 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 です。
Django は RegisterLookupMixin を使って、自分自身やそのインスタンスにルックアップを登録するインターフェイスをクラスに与えます。代表的な例は Field で、これはすべてのモデルフィールドの基底クラスです。 Transform もその一つで、これはすべての Django トランスフォームの基底クラスです。
クラスのルックアップ API を実装するミックスインです。
クラスまたはクラスのインスタンスに新しいルックアップを登録します。たとえば、次のようにします:
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 はクラスがクエリ式で使用できるように定義するメソッドの共通セットで、クラス自身を SQL 式に変換します。フィールドの直接参照、集計(Aggregation)、 Transform はこのAPIに従う例です。あるクラスが以下のメソッドを実装している場合、そのクラスはクエリ式APIに従っていると言えます:
式の 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_sql() メソッドと同じように動作します。式が compiler.compile() によってコンパイルされると、Django はまず as_vendorname() を呼び出そうとします。ここで vendorname はクエリを実行するバックエンドのベンダ名です。 vendorname は Django の組み込みバックエンドでは postgresql 、 oracle 、 sqlite 、 mysql のいずれかです。
ルックアップ名 lookup_name を返さなければなりません。インスタンスンスでは self.output_field.get_lookup(lookup_name) を返します。
ルックアップ名 transform_name を返さなければなりません。インスタンスンスでは self.output_field.get_transform(transform_name) を返します。
Transform リファレンス¶Transform はフィールドの変換を実装するための汎用クラスです。主な例は DateField を IntegerField に変換する __year です。
ルックアップ式で Transform を使用する場合の表記は <expression>__<transformation> (例 date__year) です。
このクラスは クエリ式 API に従っており、 <expression>__<transform1>__<transform2> を使用できます。これは Func() 式 に特化したもので、引数を一つだけ受け取ることができます。 また、フィルタの右辺やアノテーションとして直接使用することもできます。
このトランスフォームを lhs と rhs の両方に適用するかどうかを示すブール値です。両者の変換は rhs に対して、ルックアップ式に現れる順番で適用されます。デフォルトでは False に設定されています。たとえば、 カスタムのルックアップを書く を参照してください。
クエリ式のパース時に使用するルックアップ名です。文字列 "__" を含むことはできません。
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))
右辺 - lhs と比較されるもの。これは単なる値であったり、SQL にコンパイルされるものであったり、一般的には F() オブジェクトや QuerySet であったりします。
このルックアップの名前で、クエリ式をパースする際に識別するために使用します。文字列 "__" を含むことはできません。
デフォルトは True です。 rhs がプレーンな値の場合、 prepare_rhs はクエリのパラメータとして使用するために、その値を準備するかどうかを決定します。そのために、 lhs.output_field.get_prep_value() が定義されていれば呼び出され、そうでなければ rhs は Value() でラップされます。
compiler.compile(lhs) が返すタプル (lhs_string, lhs_params) を返します。このメソッドをオーバーライドすることで、 lhs の処理方法を調整できます。
compiler は SQLCompiler オブジェクトで、 lhs をコンパイルする際に compiler.compile(lhs) のように使用します。 connection はベンダ固有の SQL をコンパイルする際に使用します。 lhs が None でない場合は、 self.lhs の代わりに lhs を使用します。
右辺については process_lhs() と同じように扱います。
4月 02, 2025