ルックアップ API リファレンス

このドキュメントには、データベースクエリの WHERE 句を構築するための Django API であるルックアップの API リファレンスがあります。ルックアップの 使い方 については クエリを作成する を、新しいルックアップの 作り方 については カスタムのルックアップを書く を参照してください。

ルックアップAPIには2つのコンポーネントがあります。ルックアップを登録する RegisterLookupMixin クラスと、ルックアップとして登録するためにクラスが実装しなければならないメソッドのセットである クエリ式 API です。

Django には、クエリ式 API に従う 2 つの基本クラスがあり、すべての Django 組み込みルックアップはここから派生しています:

  • Lookup: フィールドをルックアップします (例えば field_name__exactexact)
  • Transform: フィールドをトランスフォーム(変換)します。

ルックアップ式は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)

このコードは DateFieldYearExact ルックアップと User.date_joinedMonthExact ルックアップを登録します( フィールドアクセス API を使用して単一のフィールドインスタンスを取得できます)。このルックアップは既に存在する同じ名前のルックアップを上書きします。フィールドインスタンスに登録されたルックアップはクラスに登録されたルックアップよりも優先されます。 lookup.lookup_name が指定された場合は lookup_name が使用され、指定されなかった場合は lookup.lookup_name が使用されます。

get_lookup(lookup_name)

クラスまたはクラスインスタンスに登録されている lookup_name という名前の Lookup を、呼び出しに応じて返します。デフォルトの実装では、全ての親クラスを再帰的にルックアップし、 lookup_name という名前のルックアップが登録されているかどうかをチェックし、最初にマッチしたものを返します。インスタンスのルックアップは同じ Lookup_name を持つクラスのルックアップを上書きします。

get_lookups()

Lookup クラスにマップされたクラスまたはクラスインスタンスに登録されているルックアップ名の辞書を返します。

get_transform(transform_name)

クラスまたはクラスインスタンスに登録されている transform_name という Transform を返します。デフォルトの実装では、すべての親クラスを再帰的に検索し、 transform_name という名前のトランスフォームが登録されているかどうかを調べ、最初にマッチしたものを返します。

クラスがルックアップであるためには、 クエリ式 API に従わなければなりません。 LookupTransform は当然この API に従います。

Changed in Django 4.2:

Field インスタンスにルックアップを登録できるようになりました。

クエリ式 API

クエリ式 API はクラスがクエリ式で使用できるように定義するメソッドの共通セットで、クラス自身を SQL 式に変換します。フィールドの直接参照、集計(Aggregation)、 Transform はこのAPIに従う例です。あるクラスが以下のメソッドを実装している場合、そのクラスはクエリ式APIに従っていると言えます:

as_sql(compiler, connection)

式の SQL フラグメントを生成します。タプル (sql, params) を返します。sql は SQL 文字列で、params はクエリパラメータのリストまたはタプルです。 compilerSQLCompiler オブジェクトで、他の式をコンパイルするための 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 の組み込みバックエンドでは postgresqloraclesqlitemysql のいずれかです。

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 はフィールドの変換を実装するための汎用クラスです。主な例は DateFieldIntegerField に変換する __year です。

ルックアップ式で Transform を使用する場合の表記は <expression>__<transformation> (例 date__year) です。

このクラスは クエリ式 API に従っており、 <expression>__<transform1>__<transform2> を使用できます。これは Func() 式 に特化したもので、引数を一つだけ受け取ることができます。 また、フィルタの右辺やアノテーションとして直接使用することもできます。

bilateral

この変換を lhsrhs の両方に適用するかどうかを示すブール値です。両者の変換は rhs に対して、ルックアップ式に現れる順番で適用されます。デフォルトでは False に設定されています。たとえば、 カスタムのルックアップを書く を参照してください。

lhs

左辺 - 変換されるもの。これは クエリ式API に従わなければなりません。

lookup_name

クエリ式のパース時に使用するルックアップ名です。文字列 "__" を含むことはできません。

output_field

この変換が出力するクラスを定義します。これは Field インスタンスでなければなりません。デフォルトでは lhs.output_field と同じです。

Lookup リファレンス

class Lookup

ルックアップ Lookup はルックアップを実装するための汎用クラスです。ルックアップは左辺 lhs; 右辺 rhs; lookup_name を持つクエリ式で、 lhs in rhslhs > rhs のように lhsrhs をブール値で比較します。

式の中でルックアップを使用するための主な記法は <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

左辺 - ルックアップされる対象。オブジェクトは通常 クエリ式API に従います。プレーンな値の場合もあります。

rhs

右辺 - lhs と比較されるもの。これは単なる値であったり、SQL にコンパイルされるものであったり、一般的には F() オブジェクトや QuerySet であったりします。

lookup_name

このルックアップの名前で、クエリ式をパースする際に識別するために使用します。文字列 "__" を含むことはできません。

prepare_rhs

デフォルトは True です。 rhs がプレーンな値の場合、 prepare_rhs はクエリのパラメータとして使用するために、その値を準備するかどうかを決定します。そのために、 lhs.output_field.get_prep_value() が定義されていれば呼び出され、そうでなければ rhsValue() でラップされます。

process_lhs(compiler, connection, lhs=None)

compiler.compile(lhs) が返すタプル (lhs_string, lhs_params) を返します。このメソッドをオーバーライドすることで、 lhs の処理方法を調整できます。

compilerSQLCompiler オブジェクトで、 lhs をコンパイルする際に compiler.compile(lhs) のように使用します。 connection はベンダ固有の SQL をコンパイルする際に使用します。 lhsNone でない場合は、 self.lhs の代わりに lhs を使用します。

process_rhs(compiler, connection)

右辺については process_lhs() と同じように扱います。

Back to Top