# Django 5.0.9.dev20240806133106 ドキュメント

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

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

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

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

- `Lookup`: フィールドをルックアップします (例えば `field_name__exact` の `exact`)
- `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)

    このコードは `DateField` の `YearExact` ルックアップと `User.date_joined` の `MonthExact` ルックアップを登録します（ フィールドアクセス 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 に従わなければなりません。 `Lookup` と `Transform` は当然この API に従います。

Changed in Django 4.2:

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

## クエリ式 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)` を返します。

`output_field`

  `get_lookup()` メソッドが返すクラスの型を定義します。これは `Field` インスタンスでなければなりません。

## `Transform` リファレンス

class `Transform`

  `Transform` はフィールドの変換を実装するための汎用クラスです。主な例は `DateField` を `IntegerField` に変換する `__year` です。

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

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

  `bilateral`

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

  `lhs`

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

  `lookup_name`

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

  `output_field`

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

## `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))

  `lhs`

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

  `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()` と同じように扱います。