# Django 5.2.9 ドキュメント

# ルックアップ 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 に従います。

## クエリ式 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`) です。

  This class follows the Query Expression API, which implies that you can use `<expression>__<transform1>__<transform2>`. It's a specialized Func() expression that only accepts one argument. It can also be used on the right hand side of a filter or directly as an annotation.

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