# Django 5.0.9.dev20240806133106 ドキュメント

# PostgreSQL 固有のモデルフィールド

これらのフィールドは全て `django.contrib.postgres.fields` モジュールから利用できます。

## これらのフィールドにインデックスを付ける

`Index` と `Field.db_index` は両方とも B-tree インデックスを作成しますが、複雑なデータ型をクエリする際にはあまり役立ちません。 `GinIndex` や `GistIndex` などのインデックスの方が適しています。ただし、適切なインデックスの選択は使用しているクエリに依存します。一般的には、GiST は 範囲フィールド や `HStoreField` には適しており、GIN は `ArrayField` に役立つかもしれません。

## `ArrayField`

class `ArrayField`(base_field, size=None, **options)

  データのリストを格納するためのフィールドです。ほとんどのフィールドタイプを使用でき、 `base_field` として別のフィールドインスタンスを渡します。 `size` を指定することもできます。`ArrayField` は、多次元配列を格納するためにネストすることもできます。

  フィールドに `default` を与える場合は、それが `list` (空のデフォルトの場合) やリストを返す呼び出し可能オブジェクト (関数など) のような呼び出し可能オブジェクトであることを確認してください。 `default=[]` を誤って使用すると、すべての `ArrayField` インスタンスで共有される変更可能なデフォルトが作成されます。

  `base_field`

    これは必須の引数です。

    配列のベースとなるデータ型や動作を指定します。これは、 `Field` のサブクラスのインスタンスである必要があります。例えば `IntegerField` や `CharField` などが考えられます。ほとんどのフィールドタイプが許容されますが、リレーショナルデータを処理するもの (`ForeignKey`, `OneToOneField`, `ManyToManyField`) やファイルフィールド (`FileField`, `ImageField`) は除外されます。

    配列フィールドは入れ子にできます。 `base_field` として `ArrayField` のインスタンスを指定できます。たとえば:

        from django.contrib.postgres.fields import ArrayField
        from django.db import models

        class ChessBoard(models.Model):
            board = ArrayField(
                ArrayField(
                    models.CharField(max_length=10, blank=True),
                    size=8,
                ),
                size=8,
            )

    データベースとモデル間の値の変換、データと設定の検証、シリアライズはすべて、基盤となるベースフィールドに委譲されます。

  `size`

    これはオプションの引数です。

    指定された場合、配列は指定された最大サイズを持ちます。これはデータベースに渡されますが、現在のところ PostgreSQL はこの制限を強制しません。

注釈

`ArrayField` を入れ子にする際、 `size` パラメータを使用するかどうかに関わらず、PostgreSQL では配列は長方形である必要があります。

    from django.contrib.postgres.fields import ArrayField
    from django.db import models

    class Board(models.Model):
        pieces = ArrayField(ArrayField(models.IntegerField()))

    # Valid
    Board(
        pieces=[
            [2, 3],
            [2, 1],
        ]
    )

    # Not valid
    Board(
        pieces=[
            [2, 3],
            [2],
        ]
    )

不規則な形状が必要な場合は、基になるフィールドをnullable にし、値を `None` でパディングする必要があります。

### `ArrayField` へのクエリ

`ArrayField` には、カスタムルックアップやトランスフォームがいくつかあります。以下のモデル例を使用します。

    from django.contrib.postgres.fields import ArrayField
    from django.db import models

    class Post(models.Model):
        name = models.CharField(max_length=200)
        tags = ArrayField(models.CharField(max_length=200), blank=True)

        def __str__(self):
            return self.name

#### `contains`

`ArrayField` 上で `contains` ルックアップはオーバーライドされます。返されるオブジェクトは、渡された値がデータの部分集合であるものです。これは SQL 演算子 `@>` を使用します。たとえば、:

    >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
    >>> Post.objects.create(name="Second post", tags=["thoughts"])
    >>> Post.objects.create(name="Third post", tags=["tutorial", "django"])

    >>> Post.objects.filter(tags__contains=["thoughts"])
    <QuerySet [<Post: First post>, <Post: Second post>]>

    >>> Post.objects.filter(tags__contains=["django"])
    <QuerySet [<Post: First post>, <Post: Third post>]>

    >>> Post.objects.filter(tags__contains=["django", "thoughts"])
    <QuerySet [<Post: First post>]>

#### `contained_by`

これは `contains` ルックアップの逆です。返されるオブジェクトは、データが渡された値の部分集合であるものです。これにはSQL演算子 `<@` が使用されます。たとえば:

    >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
    >>> Post.objects.create(name="Second post", tags=["thoughts"])
    >>> Post.objects.create(name="Third post", tags=["tutorial", "django"])

    >>> Post.objects.filter(tags__contained_by=["thoughts", "django"])
    <QuerySet [<Post: First post>, <Post: Second post>]>

    >>> Post.objects.filter(tags__contained_by=["thoughts", "django", "tutorial"])
    <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>

#### `overlap`

データが渡された値といずれか一致するオブジェクトを返します。SQL 演算子 `(&&)` を使用します。例:

    >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
    >>> Post.objects.create(name="Second post", tags=["thoughts", "tutorial"])
    >>> Post.objects.create(name="Third post", tags=["tutorial", "django"])

    >>> Post.objects.filter(tags__overlap=["thoughts"])
    <QuerySet [<Post: First post>, <Post: Second post>]>

    >>> Post.objects.filter(tags__overlap=["thoughts", "tutorial"])
    <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>

    >>> Post.objects.filter(tags__overlap=Post.objects.values_list("tags"))
    <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>

Changed in Django 4.2:

右辺としての `QuerySet.values()` と `values_list()` をサポートしました。

#### `len`

配列の長さを返します。この後に利用可能なルックアップは `IntegerField` で利用可能なものです。たとえば:

    >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
    >>> Post.objects.create(name="Second post", tags=["thoughts"])

    >>> Post.objects.filter(tags__len=1)
    <QuerySet [<Post: Second post>]>

#### インデックスのトランスフォーム

インデックスは配列内のインデックスに変換されます。非負の整数ならどれでも使用できます。配列の `size` 属性を超えていてもエラーは発生しません。変換後に利用可能なルックアップは、 `base_field` 属性から得られるものです。たとえば:

    >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
    >>> Post.objects.create(name="Second post", tags=["thoughts"])

    >>> Post.objects.filter(tags__0="thoughts")
    <QuerySet [<Post: First post>, <Post: Second post>]>

    >>> Post.objects.filter(tags__1__iexact="Django")
    <QuerySet [<Post: First post>]>

    >>> Post.objects.filter(tags__276="javascript")
    <QuerySet []>

注釈

PostgreSQL は素のSQLを記述する際、配列フィールドに1から始まるインデックスを使用します。しかし、これらのインデックスと `slices` で使用されるインデックスは、Pythonとの一貫性を保つために0から始まるインデックスを使用します。

#### スライス トランスフォーム

スライス トランスフォームは、配列の一部を切り取ります。 2つの非負整数をアンダースコアで区切って使用できます。トランスフォーム後に利用可能なルックアップは変わりません。 例を挙げると、

    >>> Post.objects.create(name="First post", tags=["thoughts", "django"])
    >>> Post.objects.create(name="Second post", tags=["thoughts"])
    >>> Post.objects.create(name="Third post", tags=["django", "python", "thoughts"])

    >>> Post.objects.filter(tags__0_1=["thoughts"])
    <QuerySet [<Post: First post>, <Post: Second post>]>

    >>> Post.objects.filter(tags__0_2__contains=["thoughts"])
    <QuerySet [<Post: First post>, <Post: Second post>]>

注釈

PostgreSQLは素のSQLを記述する際、配列フィールドに対して1から始まるインデックスを使用します。しかし、これらのスライスや `indexes` で使用されるスライスは、Pythonとの一貫性を保つために0から始まるインデックスを使用します。

インデックスとスライスを使用した多次元配列

PostgreSQL は、多次元配列でインデックスやスライスを使うときに、かなり難解な動作をします。最終的な基礎データまで到達するためにインデックスを使うのは常にうまくいきますが、他のほとんどのスライスはデータベースレベルで奇妙な動作をするので、 Django が論理的で一貫性のある方法でサポートすることはできません。

## `CIText` フィールド

class `CIText`(**options)

  バージョン 4.2 で非推奨.

  citext 型をバックエンドとする大文字小文字を区別しないテキストフィールドを作成するためのミックスインです。使用する前に the performance considerations を参照してください。

  `citext` を使用するには、最初の `CreateModel` マイグレーションオペレーションの前に、PostgreSQL で citext 拡張機能をセットアップ するために `CITextExtension` オペレーションを使用してください。

  `CIText` フィールドの `ArrayField` を使用している場合、 `INSTALLED_APPS` に `'django.contrib.postgres'` を追加する必要があります。そうしないと、フィールドの値が `'{thoughts,django}'` のような文字列として表示されます。

  ミックスインを使用するいくつかのフィールドが提供されています:

class `CICharField`(**options)

  バージョン 4.2 で非推奨: `CICharField` は、大文字小文字を区別しない非決定論的な照合順序を持つ `CharField(db_collation="…")` に置き換えられ、非推奨となりました。

class `CIEmailField`(**options)

  バージョン 4.2 で非推奨: `CIEmailField` は、大文字小文字を区別しない非決定的な照合順序を用いる `EmailField(db_collation="…")` に置き換えられ、非推奨となりました。

class `CITextField`(**options)

  バージョン 4.2 で非推奨: `CITextField` は大文字小文字を区別しない非決定的な照合順序を持つ `TextField(db_collation="…")` に置き換えられ、非推奨となりました。

  これらのフィールドはそれぞれ `CharField`、 `EmailField`、 `TextField` のサブクラスです。

  `citext` はPostgreSQLの `text` 型と同じような動作をするので、`max_length` はデータベースで強制されることはありません。

大文字小文字を区別しない照合順序 (collation)

`citext` 拡張機能の代わりに非決定的照合順序を使用するのが望ましいです。これを作成するには `CreateCollation` マイグレーションオペレーションを使用します。詳しくは マイグレーションを使って照合順序 (collation) を管理する や PostgreSQL のドキュメント non-deterministic collations を参照してください。

## `HStoreField`

class `HStoreField`(**options)

  キーと値のペアを格納するためのフィールド。Python のデータ型は `dict` です。キーは文字列でなければならず、値は文字列または NULL (Python では `None`) でなければなりません。

  このフィールドを使用するには、次のようにします:

  1. `INSTALLED_APPS` に `'django.contrib.postgres'` を追加します。
  2. PostgreSQL の hstore 拡張 を設定します。

  最初のステップをスキップすると `can't adapt type 'dict'` というエラーが表示され、2番目のステップをスキップすると `type "hstore" does not exist` というエラーが表示されます。

注釈

与えられたフィールドに対して有効なキーを要求したり、制限したりすることが有用な場合があります。これは `KeysValidator` を使って行うことができます。

### `HStoreField` へのクエリ

`HStoreField` では、キーによるクエリに加えて、多くのカスタムルックアップが利用可能です。

次のようなモデル例を使用します:

    from django.contrib.postgres.fields import HStoreField
    from django.db import models

    class Dog(models.Model):
        name = models.CharField(max_length=200)
        data = HStoreField()

        def __str__(self):
            return self.name

#### キーのルックアップ

指定されたキーに基づいてクエリを実行するには、そのキーをルックアップ名として使用します:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie"})

    >>> Dog.objects.filter(data__breed="collie")
    <QuerySet [<Dog: Meg>]>

キーのルックアップの後に他のルックアップを連結することもできます:

    >>> Dog.objects.filter(data__breed__contains="l")
    <QuerySet [<Dog: Rufus>, <Dog: Meg>]>

`F()` 式を使ってキー値にアノテーションを付けることもできます。たとえば:

    >>> from django.db.models import F
    >>> rufus = Dog.objects.annotate(breed=F("data__breed"))[0]
    >>> rufus.breed
    'labrador'

クエリしたいキーが他のルックアップの名前と衝突する場合は、代わりに `hstorefield.contains` ルックアップを使用する必要があります。

注釈

キーのトランスフォームは、 `contains`、`icontains`、`endswith`、 `iendswith`、`iexact`、`regex`、`iregex`、`startswith`、および `istartswith` ルックアップとも連結できます。

警告

どのような文字列でも hstore 値のキーになり得るので、以下に列挙されている以外のルックアップはキーのルックアップとして解釈されます。エラーは発生しません。タイプミスには特に注意し、クエリが意図したとおりに動作するか常にチェックしてください。

#### `contains`

`contains` ルックアップは、`HStoreField` 上でオーバーライドされています。返されるオブジェクトは、指定されたキーと値の `dict` がフィールド内にすべて含まれるものです。SQL 演算子 `@>` を使用します。たとえば:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador", "owner": "Bob"})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
    >>> Dog.objects.create(name="Fred", data={})

    >>> Dog.objects.filter(data__contains={"owner": "Bob"})
    <QuerySet [<Dog: Rufus>, <Dog: Meg>]>

    >>> Dog.objects.filter(data__contains={"breed": "collie"})
    <QuerySet [<Dog: Meg>]>

#### `contained_by`

これは、 `contains` ルックアップの逆です。返されるオブジェクトは、オブジェクト上のキーと値のペアが渡された値のサブセットであるものです。これは、SQL演算子 `<@` を使用します。たとえば:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador", "owner": "Bob"})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
    >>> Dog.objects.create(name="Fred", data={})

    >>> Dog.objects.filter(data__contained_by={"breed": "collie", "owner": "Bob"})
    <QuerySet [<Dog: Meg>, <Dog: Fred>]>

    >>> Dog.objects.filter(data__contained_by={"breed": "collie"})
    <QuerySet [<Dog: Fred>]>

#### `has_key`

与えられたキーがデータ内にあるオブジェクトを返します。SQL演算子は `?` を使用します。例:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})

    >>> Dog.objects.filter(data__has_key="owner")
    <QuerySet [<Dog: Meg>]>

#### `has_any_keys`

与えられたキーのいずれかがデータ内にあるオブジェクトを返します。SQL演算子 `?|` を使用します。例:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    >>> Dog.objects.create(name="Meg", data={"owner": "Bob"})
    >>> Dog.objects.create(name="Fred", data={})

    >>> Dog.objects.filter(data__has_any_keys=["owner", "breed"])
    <QuerySet [<Dog: Rufus>, <Dog: Meg>]>

#### `has_keys`

与えられたキーが全てデータ中に含まれるオブジェクトを返します。SQL演算子 `?&` を使用します。例:

    >>> Dog.objects.create(name="Rufus", data={})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})

    >>> Dog.objects.filter(data__has_keys=["breed", "owner"])
    <QuerySet [<Dog: Meg>]>

#### `keys`

与えられた値がキーの配列であるオブジェクトを返します。順序が信頼できるわけではないことに注意してください。したがって、このトランスフォームは主に `ArrayField` でのルックアップと組み合わせて使用するために便利です。SQL 関数 `akeys()` を使用します。例:

    >>> Dog.objects.create(name="Rufus", data={"toy": "bone"})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})

    >>> Dog.objects.filter(data__keys__overlap=["breed", "toy"])
    <QuerySet [<Dog: Rufus>, <Dog: Meg>]>

#### `values`

値の配列が与えられた値であるオブジェクトを返します。このトランスフォームは主に `ArrayField` のルックアップと組み合わせて使用すると便利です。SQL 関数 `avals()` を使用します。たとえば:

    >>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
    >>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})

    >>> Dog.objects.filter(data__values__contains=["collie"])
    <QuerySet [<Dog: Meg>]>

## 範囲フィールド

PostgreSQLの組み込み範囲型に対応する5つの範囲フィールド型があります。これらのフィールドは値の範囲を格納するために使用されます。例えば、イベントの開始と終了のタイムスタンプや、アクティビティに適した年齢の範囲などです。

すべての範囲フィールドはPythonでは psycopg Range オブジェクト に変換されますが、境界情報が不要な場合はタプルを入力として受け付けます。デフォルトは下界を含み、上界を含まない `[)` です (different bounds の詳細についてはPostgreSQLのドキュメントを参照してください) 。離散範囲でないフィールド (`DateTimeRangeField` と `DecimalRangeField`) のデフォルトの境界は `default_bounds` 引数で変更できます。

### `IntegerRangeField`

class `IntegerRangeField`(**options)

  整数の範囲を格納します。 `IntegerField` に基づいています。データベースでは `int4range` で表現され、 Python では `django.db.backends.postgresql.psycopg_any.NumericRange` で表現されます。

  データ保存時に指定された境界に関係なく、PostgreSQLは常に下界を含み上界を除いた正規形、つまり `[)` で範囲を返します。

### `BigIntegerRangeField`

class `BigIntegerRangeField`(**options)

  大きな整数の範囲を格納します。 `BigIntegerField` に基づいています。データベースでは `int8range` で表現され、 Python では `django.db.backends.postgresql.psycopg_any.NumericRange` で表現されます。

  データ保存時に指定された境界に関係なく、PostgreSQLは常に下界を含み上界を除いた正規形、つまり `[)` で範囲を返します。

### `DecimalRangeField`

class `DecimalRangeField`(default_bounds='[)', **options)

  浮動小数点値の範囲を格納します。 `DecimalField` に基づいています。データベースでは `numrange` で表現され、Python では `django.db.backends.postgresql.psycopg_any.NumericRange` で表現されます。

  `default_bounds`

    オプション。リストとタプルの入力に対する `bounds` の値。デフォルトは下限を含み、上限を除く `[)` です (different bounds の詳細については PostgreSQL のドキュメント を参照してください)。 `default_bounds` は `django.db.backends.postgresql.psycopg_any.NumericRange` 入力には使用されません。

### `DateTimeRangeField`

class `DateTimeRangeField`(default_bounds='[)', **options)

  タイムスタンプの範囲を格納します。 `DateTimeField` に基づいています。データベースでは `tstzrange` で表現され、Python では `django.db.backends.postgresql.psycopg_any.DateTimeTZRange` で表現されます。

  `default_bounds`

    オプション。リストとタプルの入力に対する `bounds` の値。デフォルトは下限を含み、上限を除く `[)` です (different bounds の詳細については PostgreSQL のドキュメント を参照してください)。 `default_bounds` は `django.db.backends.postgresql.psycopg_any.DateTimeTZRange` 入力には使用されません。

### `DateRangeField`

class `DateRangeField`(**options)

  日付の範囲を格納します。 `DateField` に基づいています。データベースでは `daterange` で表現され、Python では `django.db.backends.postgresql.psycopg_any.DateRange` で表現されます。

  データ保存時に指定された境界に関係なく、PostgreSQLは常に下界を含み上界を除いた正規形、つまり `[)` で範囲を返します。

### 範囲フィールドへのクエリ

範囲フィールド用のカスタムルックアップとトランスフォームが多数あります。これらは上記のすべてのフィールドで利用できますが、次の例のモデルを使います:

    from django.contrib.postgres.fields import IntegerRangeField
    from django.db import models

    class Event(models.Model):
        name = models.CharField(max_length=200)
        ages = IntegerRangeField()
        start = models.DateTimeField()

        def __str__(self):
            return self.name

また、以下のオブジェクト例も使用します:

    >>> import datetime
    >>> from django.utils import timezone
    >>> now = timezone.now()
    >>> Event.objects.create(name="Soft play", ages=(0, 10), start=now)
    >>> Event.objects.create(
    ...     name="Pub trip", ages=(21, None), start=now - datetime.timedelta(days=1)
    ... )

そして `NumericRange` も:

    >>> from django.db.backends.postgresql.psycopg_any import NumericRange

#### 包含関数

他の PostgreSQL フィールドと同様に、3つの標準の包含演算子があります。 `contains`, `contained_by`, `overlap` で、それぞれ SQL 演算子 `@>`, `<@`, `&&` が使われます。

##### `contains`

    >>> Event.objects.filter(ages__contains=NumericRange(4, 5))
    <QuerySet [<Event: Soft play>]>

##### `contained_by`

    >>> Event.objects.filter(ages__contained_by=NumericRange(0, 15))
    <QuerySet [<Event: Soft play>]>

また、`contained_by` ルックアップは範囲以外のフィールド型でも利用できます: `SmallAutoField`, `AutoField`, `BigAutoField`, `SmallIntegerField`, `IntegerField`, `BigIntegerField`, `DecimalField`, `FloatField`, `DateField`, and `DateTimeField` 。たとえば:

    >>> from django.db.backends.postgresql.psycopg_any import DateTimeTZRange
    >>> Event.objects.filter(
    ...     start__contained_by=DateTimeTZRange(
    ...         timezone.now() - datetime.timedelta(hours=1),
    ...         timezone.now() + datetime.timedelta(hours=1),
    ...     ),
    ... )
    <QuerySet [<Event: Soft play>]>

##### `overlap`

    >>> Event.objects.filter(ages__overlap=NumericRange(8, 12))
    <QuerySet [<Event: Soft play>]>

#### 比較関数

範囲フィールドは標準のルックアップをサポートしています: `lt`, `gt`, `lte`, および `gte`。これらはあまり有用ではありません。必要な場合のみ上限値を比較するように、まず下限値を比較します。これは範囲フィールドでのソートにも使用される戦略です。特定の範囲比較演算子を使用する方が良いです。

##### `fully_lt`

返される範囲は、渡された範囲よりも厳密に小さいです。つまり、返される範囲内のすべての点は、渡された範囲内のすべての点よりも小さいです。

    >>> Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
    <QuerySet [<Event: Soft play>]>

##### `fully_gt`

返される範囲は、渡された範囲よりも厳密に大きいです。つまり、返される範囲のすべての点は、渡された範囲のすべての点よりも大きくなります。

    >>> Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
    <QuerySet [<Event: Pub trip>]>

##### `not_lt`

返される範囲には、渡された範囲より小さいポイントは含まれません。つまり、返される範囲の下限は少なくとも渡された範囲の下限となります。

    >>> Event.objects.filter(ages__not_lt=NumericRange(0, 15))
    <QuerySet [<Event: Soft play>, <Event: Pub trip>]>

##### `not_gt`

返される範囲には、渡された範囲よりも大きい値が含まれませんい。つまり、返される範囲の上限は、渡された範囲の上限以下になります。

    >>> Event.objects.filter(ages__not_gt=NumericRange(3, 10))
    <QuerySet [<Event: Soft play>]>

##### `adjacent_to`

返される範囲は、渡された範囲と境界を共有します。

    >>> Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
    <QuerySet [<Event: Soft play>, <Event: Pub trip>]>

#### 境界を使ったクエリ

範囲フィールドはいくつかの追加ルックアップをサポートしています。

##### `startswith`

返されるオブジェクトは与えられた下界を持つ。ベースフィールドの有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__startswith=21)
    <QuerySet [<Event: Pub trip>]>

##### `endswith`

返されるオブジェクトは与えられた上限を持つ。ベースフィールドの有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__endswith=10)
    <QuerySet [<Event: Soft play>]>

##### `isempty`

返されるオブジェクトは空の範囲です。 `BooleanField` の有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__isempty=True)
    <QuerySet []>

##### `lower_inc`

与えられた真偽値に基づき、包含もしくは非包含な下限値を持つオブジェクトを返します。 `BooleanField` の有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__lower_inc=True)
    <QuerySet [<Event: Soft play>, <Event: Pub trip>]>

##### `lower_inf`

渡された真偽値に応じて、無限大または有界下限境界を持つオブジェクトを返します。 `BooleanField` に対して有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__lower_inf=True)
    <QuerySet []>

##### `upper_inc`

渡されたブール値に応じて、上限値を包含または非包含として持つオブジェクトを返します。これは、 `BooleanField` に対して有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__upper_inc=True)
    <QuerySet []>

##### `upper_inf`

渡された真偽値に応じて、上限が無制限 (無限) または有界のオブジェクトを返します。 `BooleanField` の有効なルックアップに連結できます。

    >>> Event.objects.filter(ages__upper_inf=True)
    <QuerySet [<Event: Pub trip>]>

### 独自の範囲型を定義する

PostgreSQLでは、独自の範囲型の定義が可能です。Djangoのモデルとフォームフィールドの実装は、以下の基本クラスを使用しており、 `psycopg` は独自の範囲型の使用を可能にする `register_range()` を提供しています。

class `RangeField`(**options)

  モデル範囲フィールドの基底クラス。

  `base_field`

    使用するモデルフィールドクラス。

  `range_type`

    使用する範囲のタイプ。

  `form_field`

    使用するフォームフィールドクラス。これは `django.contrib.postgres.forms.BaseRangeField` のサブクラスである必要があります。

class `django.contrib.postgres.forms.``BaseRangeField`

  フォームの範囲フィールドの基底クラス。

  `base_field`

    使用するフォームフィールド。

  `range_type`

    使用する範囲のタイプ。

### 範囲演算子

class `RangeOperators`

PostgreSQL は範囲データ型と共に使用できる SQL 演算子のセットを提供しています (範囲演算子の完全な詳細については the PostgreSQL documentation for the full details of range operators を参照してください) 。このクラスはタイプミスを避けるための便利な方法です。演算子名は対応するルックアップの名前と重複します。

    class RangeOperators:
        EQUAL = "="
        NOT_EQUAL = "<>"
        CONTAINS = "@>"
        CONTAINED_BY = "<@"
        OVERLAPS = "&&"
        FULLY_LT = "<<"
        FULLY_GT = ">>"
        NOT_LT = "&>"
        NOT_GT = "&<"
        ADJACENT_TO = "-|-"

### RangeBoundary() 式

class `RangeBoundary`(inclusive_lower=True, inclusive_upper=False)
  `inclusive_lower`

    `True` (デフォルト) の場合、下限値は包含される `'['` であり、そうでない場合は非包含 `'('` です。

  `inclusive_upper`

    `False` (デフォルト) なら、上限は非包含 `')'` となります。それ以外の場合は包含 `']'` となります。

`RangeBoundary()` 式は範囲の境界を表します。これは、範囲の境界を期待するカスタム範囲関数と一緒に使用できます。たとえば、 `ExclusionConstraint` を定義する際に使用されます。詳細は PostgreSQLのドキュメント を参照してください。