# Django 5.2.8 ドキュメント

# モデル

モデルは、データに関する唯一かつ決定的な情報源です。あなたが保持するデータが必要とするフィールドとその動作を定義します。一般的に、各モデルは単一のデータベースのテーブルに対応付けられます。

基本:

- モデルは各々 Python のクラスであり `django.db.models.Model` のサブクラスです。

- モデルの属性はそれぞれがデータベースのフィールドを表します。

- これら全てを用いて、Django はデータベースにアクセスする自動生成された API を提供します。 クエリを作成する を参照してください。

## 簡単な例

次の例では `first_name` と `last_name` を持つ `Person` というモデルを定義しています。

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)

`first_name` および `last_name` はこのモデルの フィールド です。各フィールドはクラスの属性として定義され、各属性はデータベースのカラムに関連付けられます。

上記の `Person` モデルは以下のようなデータベースのテーブルを作成します:

    CREATE TABLE myapp_person (
        "id" bigint NOT NULL PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
        "first_name" varchar(30) NOT NULL,
        "last_name" varchar(30) NOT NULL
    );

技術的な注意点:

- `myapp_person` というテーブル名は、いくつかのモデルのメタデータから自動的に生成されますが、それを無効化することもできます。詳細は テーブル名 を参照ください。

- `id` フィールドは自動的に追加されますが、この処理は無効化することもできます。自動インクリメントの主キーフィールド を参照ください。

- この例における `CREATE TABLE` の SQL は PostgreSQL の文法に準拠していますが、Django は 設定ファイル 内に定義されたデータベースバックエンドに合わせた SQL を適切に生成してくれるということを覚えておくとよいでしょう。

## モデルの利用

一度モデルを定義した後は、Django にこれらのモデルを 利用する ということを知らせる必要があります。そのためには、設定ファイルを編集して、設定値 `INSTALLED_APPS` に、定義した `models.py` を含むモジュール名を追加します。

たとえば、アプリケーションのモデルが `myapp.models` モジュール内に存在する場合 (このパッケージ構造は `manage.py startapp` スクリプトによってアプリケーション内に構築されるものです)、`INSTALLED_APPS` の部分を次のように定義します。

    INSTALLED_APPS = [
        # ...
        "myapp",
        # ...
    ]

`INSTALLED_APPS` 内に新たなアプリケーションを追加した場合、`manage.py migrate` を、初回は必要に応じて `manage.py makemigrations` を忘れずに実行してください。

## フィールド

モデルの最も重要な部分であり、モデルにとって唯一必須のもの、それはモデルが定義するデータベースフィールドのリストです。フィールドはクラスの属性として定義します。 `clean`, `save`, `delete` のような モデル API と衝突するフィールド名は付けられないことに注意してください。

実装例:

    from django.db import models

    class Musician(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        instrument = models.CharField(max_length=100)

    class Album(models.Model):
        artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
        name = models.CharField(max_length=100)
        release_date = models.DateField()
        num_stars = models.IntegerField()

### フィールドの型

モデル内の各フィールドは、適切な `Field` クラスのインスタンスである必要があります。Django はフィールドクラスの型に応じて以下のような挙動を決定します。

- カラムの型。これはデータベースにどの種類のデータを格納するかを示します (例: `INTEGER`、`VARCHAR`、`TEXT`)。

- フォーム領域をレンダリングする際に使用するデフォルトの HTML ウィジェット (例: `<input type="text">`、 `<select>`)。

- Django 管理サイトや自動生成フォームで使用される最小限のバリデーション要件。

Django は多くのフィールド型を内蔵しています。完全なリストは モデルフィールドのリファレンス から確認できます。もし Django に内蔵のフィールド型では実現できない機能を実装したい場合は、独自のフィールドを簡単に作成できます。詳細は カスタムのモデルフィールドを作成する を参照してください。

### フィールドオプション

フィールドはそれぞれあらかじめ定められたフィールド特有の引数 ( モデルのフィールド型一覧 にまとめられています) を受け取ります。例えば、`CharField` (およびそのサブクラス) はそのデータを保持するためにデータベース上に定義される `VARCHAR` 領域の長さを定義する引数 `max_length` を必要とします。

全てのフィールドの型で利用できる共通の引数も存在します。すべてオプションの引数です。これらの引数についてはこちらの リファレンス 内で全て説明されていますが、ここでは、特に頻繁に使われるものについて簡単な概要を説明します。

`null`

  `True` の場合、Django は空の値をデータベース内に `NULL` として保持します。デフォルトは `False` です。

`blank`

  `True` の場合、フィールドはブランクになることが許容されます。デフォルトは `False` です。

  `null` とは挙動が異なる事に注意してください。 `blank` がバリデーション由来である一方、 `null` は完全にデータベース由来です。あるフィールドが `blank=True` であれば、フォームのバリデーションは空の値の入力を許容します。あるフィールドが `blank=False` の場合は、そのフィールドへの入力は必須となります。

`choices`

  2 値タプルの sequence, もしくは mapping, 列挙型, または呼び出し可能オブジェクト (引数を指定せず、前述の形式のいずれかを返す) をこのフィールドの選択肢として使用します。これが指定された場合、デフォルトのフォームウィジェットは標準のテキストフィールドではなくセレクトボックスとなり、選択肢は指定されたものに制限されます。

  選択肢のリストは以下のようになります。

      YEAR_IN_SCHOOL_CHOICES = [
          ("FR", "Freshman"),
          ("SO", "Sophomore"),
          ("JR", "Junior"),
          ("SR", "Senior"),
          ("GR", "Graduate"),
      ]

  注釈

  `choices` の順番を変更すると、変更のたびに新しいマイグレーションが生成されます。

  各タプルの1番目の要素はデータベースに保存される値です。2番目の要素はフォームウィジェットに表示される名前です。

  モデルのインスタンスが与えられたとき、`choices` のフィールドに対して表示される値は、`get_FOO_display()` メソッドを用いてアクセスできます。たとえば、次のようになります。

      from django.db import models

      class Person(models.Model):
          SHIRT_SIZES = {
              "S": "Small",
              "M": "Medium",
              "L": "Large",
          }
          name = models.CharField(max_length=60)
          shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

      >>> p = Person(name="Fred Flintstone", shirt_size="L")
      >>> p.save()
      >>> p.shirt_size
      'L'
      >>> p.get_shirt_size_display()
      'Large'

  列挙型クラスを用いて、`choices` を簡潔に定義することもできます。

      from django.db import models

      class Runner(models.Model):
          MedalType = models.TextChoices("MedalType", "GOLD SILVER BRONZE")
          name = models.CharField(max_length=60)
          medal = models.CharField(blank=True, choices=MedalType, max_length=10)

  さらに他の例は モデルフィールドのリファレンス で見ることができます。

`default`

  そのフィールドのデフォルト値です。このオプションには特定の値または呼び出し可能オブジェクトを渡すことができます。呼び出し可能オブジェクトの場合、新しくオブジェクトが生成される度に呼び出されます。

`db_default`

  フィールドに対するデータベース計算済みのデフォルト値です。リテラル値またはデータベース関数で指定できます。

  もし `db_default` と `Field.default` の両方が指定された場合、Python コードでインスタンスを作成する際には `default` が優先されます。データベースレベルでも `db_default` が設定され、ORM の外部で行を挿入するときや、マイグレーションで新しいフィールドを追加するときに使用されます。

`help_text`

  フォームウィジェットとともに表示される追加の「ヘルプ」テキストです。この値はフィールドがフォームとして利用されない場合でもドキュメントとして役に立ちます。

`primary_key`

  `True` の場合、設定したフィールドはそのモデルの主キーとなります。

  モデルのどのフィールドにも `primary_key=True` を設定しなかった場合、Django は自動的に主キーを保持するフィールドを追加します。つまり、デフォルトの主キーフィールドの動作を変更する必要がない場合は、 `primary_key=True` を設定する必要はありません。詳しくは 自動インクリメントの主キーフィールド を参照してください。

  主キーのフィールドは読み取り専用です。もし既存のオブジェクトの主キーの値を変更して保存する操作を行うと、既存のオブジェクトに加えて新たなオブジェクトが生成されます。以下に例を示します。

      from django.db import models

      class Fruit(models.Model):
          name = models.CharField(max_length=100, primary_key=True)

      >>> fruit = Fruit.objects.create(name="Apple")
      >>> fruit.name = "Pear"
      >>> fruit.save()
      >>> Fruit.objects.values_list("name", flat=True)
      <QuerySet ['Apple', 'Pear']>

`unique`

  `True` の場合、そのフィールドはテーブル上で一意となる制約を受けます。

繰り返しになりますが、これらは特によく利用されるフィールドのオプションの概説です。完全な説明は 共通のフィールドオプションの説明 で参照できます。

### 自動インクリメントの主キーフィールド

デフォルトでは、Django は各モデルに、 `AppConfig.default_auto_field` でアプリごとに指定した型、または `DEFAULT_AUTO_FIELD` 設定でグローバルに指定した型の自動インクリメントの主キーを付与します。例えば:

    id = models.BigAutoField(primary_key=True)

独自の主キーを設定したい場合は、いずれかのフィールドで `primary_key=True` を設定してください。そうして明示的に `Field.primary_key` が設定された場合、Djangoは自動的に `id` カラムを追加しません。

各モデルには、`primary_key=True` が必ず 1 つだけ (明示的に宣言されるか、自動的に追加されるかのどちらかで) 存在する必要があります。

### 詳細 (verbose) なフィールド名

`ForeignKey`、`ManyToManyField` 、`OneToOneField` を除くすべてのフィールド型は、任意の第 1 引数として "詳細な名前 (verbose name)" を取ります。詳細な名前を指定しない場合、Django はフィールドの属性名のアンダースコアをスペースに変換したものを使って自動的に生成します。

以下の例では、詳細な名前は `"person's first name"` です:

    first_name = models.CharField("person's first name", max_length=30)

以下の例では、詳細な名前は `"first name"` です:

    first_name = models.CharField(max_length=30)

`ForeignKey`、`ManyToManyField` 、`OneToOneField` の 3 つは最初の引数にモデルクラスを必要とするので、`verbose_name` キーワード引数を使用してください:

    poll = models.ForeignKey(
        Poll,
        on_delete=models.CASCADE,
        verbose_name="the related poll",
    )
    sites = models.ManyToManyField(Site, verbose_name="list of sites")
    place = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        verbose_name="related place",
    )

慣習的に、`verbose_name` の最初の文字は大文字にしません。必要に応じて Django が自動的に変換します。

### リレーションシップ

リレーショナルデータベースの最大の強みは、テーブル同士を関連付けられることにあります。Django では、代表的な 3 つのデータベースリレーションシップを定義できます。多対 1、多対多、1 対 1 です。

#### 多対一 (many-to-one) 関係

多対 1 の関係を定義するには、`django.db.models.ForeignKey` を使用します。使い方は他の `Field` 型と同様で、モデルのクラス属性として含めます。

`ForeignKey` には位置引数が1つ必要で、ここにはモデルと関係付けるクラスを指定します。

たとえば、`Car` モデル `Manufacturer` を持っている場合、つまり、 `Manufacturer` は複数の car を作る一方で `Car` は 1 つしか `Manufacturer` を持たない場合、以下の定義を使用してください。

    from django.db import models

    class Manufacturer(models.Model):
        # ...
        pass

    class Car(models.Model):
        manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE)
        # ...

再帰的なリレーションシップ (自分自身に対する多対 1 の関係を持つオブジェクト) や まだ定義されていないモデルへのリレーションシップ を作成することもできます。詳細は モデルフィールドのリファレンス を参照してください。

必須ではありませんが、`ForeignKey` フィールド名 (上記の例では `manufacturer`) はモデル名を小文字にしたものをおすすめします。もちろん、どんなフィールドでも呼び出すことができます。例えば、以下のようなフィールド名にすることも可能です。

    class Car(models.Model):
        company_that_makes_it = models.ForeignKey(
            Manufacturer,
            on_delete=models.CASCADE,
        )
        # ...

参考

`ForeignKey` フィールドは多数の追加的な引数を受け入れます。これらは モデルフィールドのリファレンス にて説明しています。これらの引数は、リレーションシップがどのように動作すべきかを定義するのに役立ちます。追加の引数はすべて任意です。

逆方向のリレーションシップを持つオブジェクトへのアクセスの詳細については、下記の 逆方向のリレーションシップの例 を参照してください。

サンプルのコードは、多対多のリレーションシップモデルの例 を参照してください。

#### 多対多 (many-to-many) 関係

多対多のリレーションシップを定義するには、`django.db.models.ManyToManyField` を使用してください。使い方は他の `Field` 型と同様で、モデルのクラス属性として含めます。

`ManyToManyField` には位置引数として、モデルと関連付けるクラスを指定する必要があります。

たとえば、`Pizza` が複数の `Topping` オブジェクトを持っている（そして `Topping` は複数の pizza に載ることができ、 `Pizza` は複数の topping を持つ）場合、以下のように表現できます。

    from django.db import models

    class Topping(models.Model):
        # ...
        pass

    class Pizza(models.Model):
        # ...
        toppings = models.ManyToManyField(Topping)

`ForeignKey` と同様に、再帰的なリレーションシップ (自分自身に対する多対多のリレーションシップを持つオブジェクト) や まだ定義されていないモデルへのリレーションシップ を作成することもできます。

必須ではありませんが、`ManyToManyField` フィールド (上記の例では `toppings`) はリレーション先のモデルオブジェクトの複数形が推奨されています。

どちらのモデルに `ManyToManyField` を定義しても構いませんが、片方のモデルだけに定義してください。両方に定義してはいけません。

一般に、 `ManyToManyField` は、自身のモデルのフォームで編集することが自然な方のモデルに置くべきです。上の例で言えば、トッピングが複数のピザの上にあると考えるよりは、ピザが複数のトッピングを持つと考えた方が自然なので、(`Topping` が `pizzas` という `ManyToManyField` を持つのではなく) `Pizza` が `toppings` フィールドを持つようにします。こうすることで、ユーザーは `Pizza` のフォームでトッピングを選べるようになります。

参考

完全な実装例は 多対多のリレーションシップモデルの例 を参照してください。

`ManyToManyField` フィールドは多数の追加的な引数を受け入れます。これらは モデルフィールドのリファレンス にて説明しています。これらの引数は、リレーションシップがどのように動作すべきかを定義するのに役立ちます。引数はすべて任意です。

#### 多対多のリレーションシップにおける追加フィールド

ピザとトッピングを組み合わせる程度の多対多リレーションを扱うのであれば、標準の `ManyToManyField` で十分でしょう。しかし、2 つのモデルのリレーションに他のデータを付加したくなることもあります。

たとえば、ミュージシャンが所属する音楽グループを追跡するアプリについて考えてみましょう。ミュージシャンとグループの間には多対多の関係があるので、この関係を表すのに `ManyToManyField` が使えます。しかし、ある人がそのグループに加入した日などといった多くの詳細情報も集めたいとします。

このような場合、 Django ではそのような多対多のリレーションシップを規定するのに使われるモデルを指定できます。そうすることで、中間モデルに追加のフィールドを配置できます。中間モデルは、 `through` 引数で中間として振る舞うモデルを指定することで、 `ManyToManyField` に紐付けることができます。ミュージシャンの例では、コードはこのようになるでしょう:

    from django.db import models

    class Person(models.Model):
        name = models.CharField(max_length=128)

        def __str__(self):
            return self.name

    class Group(models.Model):
        name = models.CharField(max_length=128)
        members = models.ManyToManyField(Person, through="Membership")

        def __str__(self):
            return self.name

    class Membership(models.Model):
        person = models.ForeignKey(Person, on_delete=models.CASCADE)
        group = models.ForeignKey(Group, on_delete=models.CASCADE)
        date_joined = models.DateField()
        invite_reason = models.CharField(max_length=64)

        class Meta:
            constraints = [
                models.UniqueConstraint(
                    fields=["person", "group"], name="unique_person_group"
                )
            ]

中間モデルを指定する場合は、多対多のリレーションシップに参加するモデルに対する外部キーを明示的に指定します。明示的に指定することで、ふたつのモデルがどのように関係するかが定義されます。

同じインスタンス同士の関連を重複して持たせたくない場合は、 `from` フィールドと `to` フィールドを含む `UniqueConstraint` を追加してください。Django が自動生成する多対多のテーブルには、この制約が含まれています。

中間モデルにはいくつかの制約があります。

- 中間モデルには、ソースモデル（この例では `Group` ）への外部キーが ただ1つだけ 含まれている必要があります。または、Djangoがリレーションシップに使用すべき外部キーを `ManyToManyField.through_fields` を使用して明示的に指定する必要があります。もし複数の外部キーがあり、 `through_fields` が指定されていない場合、バリデーションエラーが発生します。ターゲットモデル（この例では `Person` ）への外部キーにも同様の制限が適用されます。

- 中間モデルを介して自身と多対多のリレーションシップを持つモデルでは、同じモデルを参照する外部キーを2本まで許可できますが、それらは多対多関係の2つの（異なる）側として扱われます。 `through_fields` を指定しない場合、最初の外部キーが `ManyToManyField` の送信側、2番目の外部キーが受信側として解釈されます。ただし、外部キーが2本を 超える 場合は、どの外部キーを使用するかを明示するために `through_fields` を必ず指定する必要があります。指定しない場合はバリデーションエラーが発生します。

これで `ManyToManyField` が中間モデル (この場合は `Membership`) を使うように設定できたので、多対多のリレーションシップを作成する準備ができました。これを行うには、中間モデルのインスタンスを作成します:

    >>> ringo = Person.objects.create(name="Ringo Starr")
    >>> paul = Person.objects.create(name="Paul McCartney")
    >>> beatles = Group.objects.create(name="The Beatles")
    >>> m1 = Membership(
    ...     person=ringo,
    ...     group=beatles,
    ...     date_joined=date(1962, 8, 16),
    ...     invite_reason="Needed a new drummer.",
    ... )
    >>> m1.save()
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>]>
    >>> ringo.group_set.all()
    <QuerySet [<Group: The Beatles>]>
    >>> m2 = Membership.objects.create(
    ...     person=paul,
    ...     group=beatles,
    ...     date_joined=date(1960, 8, 1),
    ...     invite_reason="Wanted to form a band.",
    ... )
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>]>

また、 `add()` や `create()` 、 `set()` を使ってリレーションシップを作成することもできます（`through_defaults` フィールドの指定は必須です）:

    >>> beatles.members.add(john, through_defaults={"date_joined": date(1960, 8, 1)})
    >>> beatles.members.create(
    ...     name="George Harrison", through_defaults={"date_joined": date(1960, 8, 1)}
    ... )
    >>> beatles.members.set(
    ...     [john, paul, ringo, george], through_defaults={"date_joined": date(1960, 8, 1)}
    ... )

中間モデルのインスタンスを直接作成したいこともあるでしょう。

中間モデルで定義されたカスタムスルーテーブルが `(model1, model2)` ペアの一意性を強制せず、複数の値を許容する場合、 `remove()` 呼び出しは全ての中間モデルインスタンスを削除します:

    >>> Membership.objects.create(
    ...     person=ringo,
    ...     group=beatles,
    ...     date_joined=date(1968, 9, 4),
    ...     invite_reason="You've been gone for a month and we miss you.",
    ... )
    >>> beatles.members.all()
    <QuerySet [<Person: Ringo Starr>, <Person: Paul McCartney>, <Person: Ringo Starr>]>
    >>> # This deletes both of the intermediate model instances for Ringo Starr
    >>> beatles.members.remove(ringo)
    >>> beatles.members.all()
    <QuerySet [<Person: Paul McCartney>]>

`clear()` メソッドを使用すると、インスタンスの多対多の関係を全て削除できます:

    >>> # Beatles have broken up
    >>> beatles.members.clear()
    >>> # Note that this deletes the intermediate model instances
    >>> Membership.objects.all()
    <QuerySet []>

多対多のリレーションシップを確立したら、クエリを発行できます。通常の多対多のリレーションシップと同様に、多対多のリレーション先モデルの属性を使用してクエリを発行できます:

    # Find all the groups with a member whose name starts with 'Paul'
    >>> Group.objects.filter(members__name__startswith="Paul")
    <QuerySet [<Group: The Beatles>]>

中間モデルを使用しているので、その属性に対してクエリを実行することもできます:

    # Find all the members of the Beatles that joined after 1 Jan 1961
    >>> Person.objects.filter(
    ...     group__name="The Beatles", membership__date_joined__gt=date(1961, 1, 1)
    ... )
    <QuerySet [<Person: Ringo Starr]>

メンバーシップの情報にアクセスする必要がある場合は、直接 `Membership` モデルにクエリを実行してください。

    >>> ringos_membership = Membership.objects.get(group=beatles, person=ringo)
    >>> ringos_membership.date_joined
    datetime.date(1962, 8, 16)
    >>> ringos_membership.invite_reason
    'Needed a new drummer.'

同じ情報にアクセスするもう一つの方法は、 `Person` オブジェクトから 多対多の逆リレーションシップ を問い合わせることです:

    >>> ringos_membership = ringo.membership_set.get(group=beatles)
    >>> ringos_membership.date_joined
    datetime.date(1962, 8, 16)
    >>> ringos_membership.invite_reason
    'Needed a new drummer.'

#### 一対一 (one-to-one) 関係

1対1のリレーションシップを定義するには、 `OneToOneField` を使用します。使い方は他の `Field` タイプと同様で、モデルのクラス属性として含めます。

あるオブジェクトが他のオブジェクトを何らかの方法で「拡張 (extends)」しているとき、オブジェクトの主キーに設定するのが最も便利です。

`OneToOneField` には1つの位置引数として、モデルと関連付けるクラスを指定する必要があります。

例えば、"場所" のデータベースを構築する場合、住所や電話番号などの標準的なものをデータベースに構築します。そして、その場所の上にレストランのデータベースを構築したい場合、 `Restaurant` モデルにこれらのフィールドを複製する代わりに、 `Restaurant` に `Place` に対する `OneToOneField` を持たせることができます (レストランは「場所」だからです。実際、これを扱うには、暗黙の一対一関係を含む 継承 を使うのが一般的です)。

`ForeignKey` と同様に、再帰的なリレーションシップ や まだ定義されていないモデルへの参照 を作成することもできます。

参考

完全な実装例は、1対1リレーションモデルの例 を参照してください。

`OneToOneField` フィールドには、オプションの `parent_link` 引数を指定することもできます。

以前は `OneToOneField` クラスが自動的にモデルの主キーになっていました。しかし、現在はそうではありません (手動で `primary_key` 引数を渡すこともできます)。このため、1つのモデルに `OneToOneField` 型のフィールドを複数持つことができるようになりました。

### ファイルを横断したモデル

モデルを他のアプリのモデルと関連付けることも全く問題ありません。これを行うには、モデルが定義されているファイルの先頭で、関連するモデルをインポートします。そして、必要なところで他のモデルクラスを参照してください。たとえば、次のようにします:

    from django.db import models
    from geography.models import ZipCode

    class Restaurant(models.Model):
        # ...
        zip_code = models.ForeignKey(
            ZipCode,
            on_delete=models.SET_NULL,
            blank=True,
            null=True,
        )

代わりに、関連モデルへの参照を文字列 `"app_label.ModelName"` で遅延参照することもできます。この方法では、関連モデルをインポートする必要はありません。たとえば：

    from django.db import models

    class Restaurant(models.Model):
        # ...
        zip_code = models.ForeignKey(
            "geography.ZipCode",
            on_delete=models.SET_NULL,
            blank=True,
            null=True,
        )

詳しくは 遅延リレーションシップ を参照してください。

### フィールド名の制約

Django はモデルのフィールド名にいくつかの制約を課しています。

1. フィールド名はPythonの予約語にはできません。Pythonの構文エラーになるからです。たとえば次のようなものです:

       class Example(models.Model):
           pass = models.IntegerField() # 'pass' is a reserved word!

2. フィールド名には連続したアンダースコアを2つ以上含めることはできません。これはDjangoのクエリルックアップ構文のためです。たとえば次のようなものです:

       class Example(models.Model):
           foo__bar = models.IntegerField()  # 'foo__bar' has two underscores!

3. 同様の理由で、フィールド名の最後をアンダースコアにすることはできません。

4. フィールド名に `check` を指定することはできません。これは、チェックフレームワークの `Model.check()` メソッドを上書きしてしまうためです。

しかし、これらの制約を回避する手段はあります。なぜなら、フィールド名は必ずしもデータベースのカラム名と一致する必要はないからです。詳細については `db_column` オプションをご覧ください。

ただし、`join`、`where`、`select` などの SQL の予約語はモデルのフィールド名に使用できます。これは、Django がすべての SQL クエリに対して、データベースデーブル名とカラム名のエスケープを行っているためです。エスケープ処理では、使用しているデータベースエンジンのクオート構文を利用しています。

### カスタムのフィールドタイプ

既存のモデルフィールドが目的に適わない場合、あるいは一般的ではないデータベースカラム型を利用したいと考えチエル場合、独自のフィールドクラスを作成できます。自分自身のフィールドを作成する方法は、カスタムのモデルフィールドを作成する で提供しています。

## `Meta` オプション

内側に `class Meta` というクラスを定義することで、モデルのメタデータを設定できます。

    from django.db import models

    class Ox(models.Model):
        horn_length = models.IntegerField()

        class Meta:
            ordering = ["horn_length"]
            verbose_name_plural = "oxen"

モデルのメタデータには「フィールド以外のすべての事項」が設定できます。例えば、並び替えオプション (`ordering`)、データベースのテーブル名 (`db_table`)、人が読むための単数形と複数形の名前 (`verbose_name` と `verbose_name_plural`) などです。必須のものはなく、`class Meta` のモデルへの追加は完全にオプションです。

`Meta` に指定できるオプションの完全なリストは、モデルオプションリファレンス で確認できます。

## モデルの属性

`objects`

  モデルの最も重要な属性は `Manager` です。これは、Django のモデルにデータベースクエリの操作を渡すインターフェースで、データベースから インスタンスを取り出す ために使われます。`Manager` が定義されていない場合、デフォルトの名前は `objects` となります。マネージャはモデルクラスを通じてのみアクセスできます。インスタンスからはアクセスできません。

## モデルのメソッド

オブジェクトに独自の "行レベルの" 機能を追加するには、カスタムのメソッドを定義してください。`Manager` メソッドは "テーブル単位の" 操作をするように意図されており、モデルメソッドは特定のモデルインスタンス上で動作します。

これは、ビジネスロジックを 1 つの場所（モデル）で管理するための重要なテクニックです。

例えば、以下のモデルはいくつかのカスタムメソッドを持ちます:

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        birth_date = models.DateField()

        def baby_boomer_status(self):
            "Returns the person's baby-boomer status."
            import datetime

            if self.birth_date < datetime.date(1945, 8, 1):
                return "Pre-boomer"
            elif self.birth_date < datetime.date(1965, 1, 1):
                return "Baby boomer"
            else:
                return "Post-boomer"

        @property
        def full_name(self):
            "Returns the person's full name."
            return f"{self.first_name} {self.last_name}"

例にある最後のメソッドは property です。

モデルインスタンスのリファレンス には各モデルに自動的に与えられる メソッド の完全なリストがあります。ほとんどはオーバーライドできます（後述の overriding predefined model methods を参照してください）が、特によく定義することになるものがあります：

`__str__()`

  Python の「マジックメソッド」で、任意のオブジェクトの文字列表現を返します。Python や Django がモデルインスタンスを文字列として表示する際に、このメソッドが使用されます。最も典型的な例は、インタラクティブなコンソールや管理画面でオブジェクトを表示するときです。

  このメソッドは必ず定義することを推奨します。デフォルト値はあまり役に立ちません。

`get_absolute_url()`

  Django にオブジェクトの URL の計算方法を定義します。Django はこのメソッドを admin インターフェイスで利用しており、オブジェクトの URL を使用する必要があるあらゆる場面でも使用されます。

  ユニークに特定できる URL を持つすべてのオブジェクトには、このメソッドを定義しなければなりません。

### 定義済みのモデルメソッドをオーバーライドする

別の一連の モデルメソッド を使って、多くのカスタマイズしたいデータベース動作をカプセル化できます。特に、`save()` や `delete()` の動作を変更したいことがよくあります。

これらのメソッド (および他のすべてのメソッド) は自由にオーバーライドして、動作を変更できます。

ビルトインのメソッドをオーバーライドする典型的な状況は、オブジェクトを保存するとき毎回何かを実行したい、という場合です。例えば (受け入れるパラメータについては `save()` を参照してください):

    from django.db import models

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def save(self, **kwargs):
            do_something()
            super().save(**kwargs)  # Call the "real" save() method.
            do_something_else()

保存しないようにすることもできます:

    from django.db import models

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()

        def save(self, **kwargs):
            if self.name == "Yoko Ono's blog":
                return  # Yoko shall never have her own blog!
            else:
                super().save(**kwargs)  # Call the "real" save() method.

親クラスのメソッド、つまり `super().save(**kwargs)` を忘れずに呼び出すようにします。これを呼び出さないと、オブジェクトがデータベースに保存されなくなります。親クラスのメソッドを呼び出さない場合、デフォルトの動作が行われず、データベースに変更が反映されません。

また、モデルメソッドに渡される可能性のある引数をそのまま渡すことも重要です。これが `**kwargs` の役割です。Djangoは時折、組み込みのモデルメソッドの機能を拡張し、新しいキーワード引数を追加します。メソッド定義で `**kwargs` を使用しておけば、これらの引数が追加された際にも自動的に対応できるようになります。

`save()` メソッド内のフィールドの値をアップデートしたい場合は、`update_fields` キーワード引数に追加されたこのフィールドを持ちたくなるかもしれません。これにより、`update_fields` が指定されたときにフィールドが保存されることが保証されます。次に例を示します。

    from django.db import models
    from django.utils.text import slugify

    class Blog(models.Model):
        name = models.CharField(max_length=100)
        slug = models.TextField()

        def save(self, **kwargs):
            self.slug = slugify(self.name)
            if (
                update_fields := kwargs.get("update_fields")
            ) is not None and "name" in update_fields:
                kwargs["update_fields"] = {"slug"}.union(update_fields)
            super().save(**kwargs)

詳しくは どのフィールドを保存するか指定する を読んでください。

オーバーライドされたモデルメソッドは一括操作では呼び出されません

Note that the `delete()` method for an object is not necessarily called when deleting objects in bulk using a QuerySet or as a result of a `cascading delete`. To ensure customized delete logic gets executed, you can use `pre_delete` and/or `post_delete` signals.

Unfortunately, there isn't a workaround when `creating` or `updating` objects in bulk, since none of `save()`, `pre_save`, and `post_save` are called.

### カスタムの SQL を実行する

その他のよくあるパターンとしては、カスタムの SQL 文をモデルのメソッドやモジュールのメソッドとして定義することがあります。生の SQL 文を使用する方法については、生の SQL を使用する を参照してください。

## モデルの継承

Django におけるモデルの継承は Python における普通のクラスの継承とほぼ同じ方法で行われますが、最初の段階だけでもここで説明しておいた方がよいでしょう。それはその基底クラスが `django.db.models.Model` のサブクラスでなければならないという事です。

唯一決めるべきことは、親モデルを (保持するデータベースのテーブルと共に) 独自の権限を持ったモデルとするか、それとも子モデルを通じてのみ共通情報を参照する単なる保持者とするかです。

Django において可能な継承には 3 つの方式があります。

1. 子モデルそれぞれに対して一々定義し直さないで済ませたい情報を保持するためだけに、親クラスを使用することがあるかもしれません。このクラスが単体で用いられることはないので、この場合 抽象基底クラス が適切です。

2. もし既存のモデル (完全に別のアプリケーション等から取得した) のサブクラスを作成していてモデルそれぞれにデータベース上のテーブルを定義したい場合、 マルチテーブル継承 を利用するとよいでしょう。

3. 最後に、モデルの Python レベルでの振る舞いを、モデルのフィールドを変更せずに修正したい場合は、 プロキシモデル を利用できます。

### 抽象基底クラス

抽象基底クラスは、複数の他モデルに対して共通の情報を入れ込みたいときに有用です。基底クラスを書いて Meta クラス内で `abstract=True` をセットしてください。これで、このモデルはデータベーステーブルを作成するために使用されることはなくなります。 代わりに、他のモデルで基底クラスとして使われる際に、これら子クラスのフィールドとして追加されます。

実装例:

    from django.db import models

    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()

        class Meta:
            abstract = True

    class Student(CommonInfo):
        home_group = models.CharField(max_length=5)

`Student` モデルは `name`、`age` そして `home_group` の 3 つのフィールドを持つことになります。 `CommonInfo` モデルは抽象基底クラスであるため、通常の Django モデルとしては利用できません。データベース上にテーブルを生成したりマネージャを持ったりせず、そしてインスタンス化されたり直接値を保存する事もできません。

抽象基底クラスを継承したフィールドは、他のフィールドや値でオーバーライドしたり、 `None` を使って削除したりできます。

多くの場合、このタイプのモデル継承があなたの必要としているものでしょう。この方式では、データベースレベルでは子モデルごとのテーブルを 1 つずつ作る一方で、共通情報を Python レベルで因数分解できます。

#### `Meta` の継承

抽象基底クラスを作成した際、Django は基底クラスで宣言したすべての Meta インナークラスを子クラスの属性とします。子クラスが自身の Meta クラスを定義しなければ、親の Meta クラスを継承します。子クラスが親の Meta クラスを拡張したい場合、サブクラス化できます。例えば:

    from django.db import models

    class CommonInfo(models.Model):
        # ...
        class Meta:
            abstract = True
            ordering = ["name"]

    class Student(CommonInfo):
        # ...
        class Meta(CommonInfo.Meta):
            db_table = "student_info"

抽象基底クラスを継承したとき、 Django は Meta 属性に `abstract=False` をセットしてから子クラスに引き継ぎます。そのため、抽象基底クラスを継承した子クラスが自動的に抽象クラスになることはありません。抽象基底クラスを継承して新たな抽象基底クラスを作る場合は、子クラスに `abstract=True` を明示的にセットする必要があります。

抽象基底クラスの Meta クラスに持っても意味をなさない属性がいくつか存在します。例えば、属性値 `db_table` を指定することは、子クラス (のうち自身の Meta を定義していないもの) が全て同じデータベース上のテーブルを利用することを意味しますが、これは明らかに必要なものではありません。

Python の継承の仕組みにより、子クラスが複数の抽象基底クラスから継承する場合、デフォルトでは、最初にリストされたクラスの Meta オプションのみが継承されます。複数の抽象基底クラスから Meta オプションを継承するには、Meta の継承を明示的に宣言する必要があります。以下に例を示します。

    from django.db import models

    class CommonInfo(models.Model):
        name = models.CharField(max_length=100)
        age = models.PositiveIntegerField()

        class Meta:
            abstract = True
            ordering = ["name"]

    class Unmanaged(models.Model):
        class Meta:
            abstract = True
            managed = False

    class Student(CommonInfo, Unmanaged):
        home_group = models.CharField(max_length=5)

        class Meta(CommonInfo.Meta, Unmanaged.Meta):
            pass

#### `related_name` と `related_query_name` の利用に関して注意するべき点

`ForeignKey` もしくは `ManyToManyField` に対して `related_name` または `related_query_name` を使う場合、そのフィールドに対して 一意の 逆引き名およびクエリ名を常に定義しなければなりません。これは抽象基底クラスにおいて、フィールドが継承した子クラスそれぞれに含まれ、継承される毎にその属性値が完全に同じ値 (`related_name` と `related_query_name` も含む) となるため、通常問題となります。

この問題に対処するため、抽象基底クラスにおいて `related_name` もしくは `related_query_name` を用いる場合(のみ)、その値の一部に `'%(app_label)s'` と `'%(class)s'` を含まなければなりません。

- `'%(class)s'` は、フィールドが使用されている子クラスの名前を小文字にした文字列と置換されます。

- `'%(app_label)s'` は、子クラスが含まれているアプリ名を小文字にした文字列と置換されます。各インストールアプリケーション名はユニークでなければならず、モデルクラスの名は各アプリ内でもユニークでなければなりません。その結果、すべての名前が異なるものとなります。

例として、次のような `common/models.py` というアプリケーションが存在したとします。

    from django.db import models

    class Base(models.Model):
        m2m = models.ManyToManyField(
            OtherModel,
            related_name="%(app_label)s_%(class)s_related",
            related_query_name="%(app_label)s_%(class)ss",
        )

        class Meta:
            abstract = True

    class ChildA(Base):
        pass

    class ChildB(Base):
        pass

別のアプリケーションの `rare/models.py` も存在するとします。

    from common.models import Base

    class ChildB(Base):
        pass

`common.ChildA.m2m` フィールドの逆引き名は `common_childa_related` で、逆引きクエリ名は `common_childas` になります。 `common.ChildB.m2m` フィールドの逆引き名は `common_childb_related` で、逆引きクエリ名は `common_childbs` になります。最後に、 `rare.ChildB.m2m` フィールドの逆引き名は `rare_childb_related` で、逆引きクエリ名は `rare_childbs` になります。related name あるいは related query name の中で `'%(app_label)s'` と `'%(class)s'` をどう使うかは任意ですが、それらの値自体を入れ忘れた場合、Django はシステムチェックの実行時 (もしくは `migrate` の実行時) にエラーを発生させます。

もし、抽象基底クラスでフィールドに `related_name` 属性を指定しなかった場合、デフォルトの逆引き名は、子クラスの名前に `'_set'` を付けたものになります。これは、フィールドを直接子クラスに宣言した場合と同じです。例えば、上記のコードで `related_name` 属性が省略された場合、`m2m` フィールドの逆引き名は、`ChildA` の場合は `childa_set`、`ChildB` の場合は `childb_set` になります。

### マルチテーブル継承

Django がサポートするもう一つのモデル継承は、ヒエラルキー内の各モデルすべてが、それ自体モデルであるような場合です。それぞれのモデルはデータベース上のテーブルに対応しており、個別にクエリーを作成したり、テーブルの作成ができます。継承の関係によって、(自動的に作成される `OneToOneField` を通して) 子モデルとその親モデルとの間にリンクが作られます。この継承を利用すると、たとえば、次のように書くことができます。

    from django.db import models

    class Place(models.Model):
        name = models.CharField(max_length=50)
        address = models.CharField(max_length=80)

    class Restaurant(Place):
        serves_hot_dogs = models.BooleanField(default=False)
        serves_pizza = models.BooleanField(default=False)

データはデータベースの異なるテーブルに存在しますが、`Place` のすべてのフィールドは `Restaurant` でも利用できます。したがって、以下はともに可能です。

    >>> Place.objects.filter(name="Bob's Cafe")
    >>> Restaurant.objects.filter(name="Bob's Cafe")

もし、`Restaurant` でもある `Place` が存在する時、小文字にしたモデル名を使うことで、`Place` オブジェクトから `Restaurant` オブジェクトを取得できます。

    >>> p = Place.objects.get(id=12)
    # If p is a Restaurant object, this will give the child class:
    >>> p.restaurant
    <Restaurant: ...>

しかし、上の例において `p` が `Restaurant` オブジェクト ではない 場合 (つまり、継承を用いず `Place` オブジェクトが直接作成されたもしくは他のクラスの親であった場合)、`p.restaurant` を参照すると、`Restaurant.DoesNotExist` 例外が発生します。

`Restaurant` 上には次のように、 `Place` と関連付けられた `OneToOneField` が自動生成されます。

    place_ptr = models.OneToOneField(
        Place,
        on_delete=models.CASCADE,
        parent_link=True,
        primary_key=True,
    )

`Restaurant` 上で、自分自身の `OneToOneField` を `parent_link=True` を付けて宣言すれば、このフィールドをオーバーライドできます。

#### `Meta` とマルチテーブル継承

マルチテーブル継承においては、子クラスが親クラスの Meta クラスを継承することは意味がありません。すべての Meta オプションは既に親クラスに適用されており、それらを再度適用すると通常は矛盾した動作につながるだけです（これは、基底クラスが独自の権利を持たない抽象基底クラスの場合とは対照的です）。

したがって、子モデルは親の Meta クラスへのアクセスを持ちません。しかし、ごく限られたケースにおいて、子モデルは親から振る舞いを継承します。具体的には、子モデルで `ordering` 属性もしくは `get_latest_by` 属性を指定しなかった場合、これらは親モデルから継承されます。

もし親モデルが ordering 属性を持っているが、子モデルに既定のデータ並び順を持たせたくない場合は、下記のように明示的に無効化できます。

    class ChildModel(ParentModel):
        # ...
        class Meta:
            # Remove parent's ordering effect
            ordering = []

#### 継承と関係の逆引き

Because multi-table inheritance uses an implicit `OneToOneField` to link the child and the parent, it's possible to move from the parent down to the child, as in the above example. However, this uses up the name that is the default `related_name` value for `ForeignKey` and `ManyToManyField` relations. If you are putting those types of relations on a subclass of the parent model, you must specify the `related_name` attribute on each such field. If you forget, Django will raise a validation error.

例として、上で用いた `Place` クラスを再度用いて、また別のサブクラスを `ManyToManyField` によって作成してみましょう:

    class Supplier(Place):
        customers = models.ManyToManyField(Place)

この処理の結果はエラーとなります。

    Reverse query name for 'Supplier.customers' clashes with reverse query
    name for 'Supplier.place_ptr'.

    HINT: Add or change a related_name argument to the definition for
    'Supplier.customers' or 'Supplier.place_ptr'.

`customers` フィールドに `related_name` を追加する事でこのエラーを解消できます: `models.ManyToManyField(Place, related_name='provider')`。

#### 親モデルとの関連付けに用いるフィールドを定義する

前述のように、Django は、非抽象の親モデルにリンクする `OneToOneField` を子クラスに自動的に作成します。親モデルへのリンクとなる属性の名前を自分で決めたい場合は、 `OneToOneField` を手動で作成し、そのフィールドが親クラスへのリンクであることを示すために `parent_link=True` を設定します。

### プロキシモデル

マルチテーブル継承 を使用すると、モデルの各サブクラスに対して新しいデータベーステーブルが作成されます。これは通常、望ましい動作です。なぜなら、サブクラスには基底クラスに存在しない追加のデータフィールドを格納する場所が必要だからです。しかし、時にはモデルの Python 上での動作を変更したいだけの場合もあります。たとえば、デフォルトマネージャーを変更する、新しいメソッドを追加するなどです。

これがプロキシモデル継承の目的、つまり元のモデルの プロキシ を作成することです。プロキシモデルのインスタンスは作成、削除、更新でき、すべてのデータは元の（非プロキシ）モデルを使用しているかのように保存されます。違いは、元のモデルを変更することなく、デフォルトのモデルのソート順やマネージャーの設定をプロキシ上で変更できるという点です。

プロキシモデルは通常のモデルと同様に定義されます。Django にそれがプロキシモデルである事を伝えるには `Meta` クラスの `proxy` 属性値を `True` にします。

例として、`Person` モデルにメソッドを追加する場合は、次のように書くことができます。

    from django.db import models

    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)

    class MyPerson(Person):
        class Meta:
            proxy = True

        def do_something(self):
            # ...
            pass

MyPerson クラスは、親クラスである Person クラスと同じデータベーステーブルを操作します。特に、新たに作成された Person のインスタンスは MyPerson を通じてもアクセス可能であり、その逆も同様です。

    >>> p = Person.objects.create(first_name="foobar")
    >>> MyPerson.objects.get(first_name="foobar")
    <MyPerson: foobar>

プロキシモデルを使用して、モデルに異なるデフォルトの並び順を定義することもできます。`Person` モデルの並び順を常に指定したいわけではなくても、プロキシを利用することで、規則的に `last_name` 属性で並び替えることができます。

    class OrderedPerson(Person):
        class Meta:
            ordering = ["last_name"]
            proxy = True

これにより、通常の `Person` に対するクエリは並び順が指定されず、`OrderedPerson` に対するクエリでは `last_name` に基づいて並び替えられるようになります。

プロキシモデルは `Meta` の属性値を 通常のモデルと同様に 継承します。

#### `QuerySet`s はリクエストされたモデルを返し続ける

Django では、例えば `Person` オブジェクトにクエリした際に、`MyPerson` オブジェクトを返すようにする方法はありません。`Person` オブジェクトのクエリセットは、そのまま `Person` オブジェクトを返します。プロキシオブジェクトのポイントは、`Person` モデルに依存するコードはそのまま `Person` を使用しつつ、コード上ではあなたが独自に書いた拡張を利用できることにあります（他のコードがその拡張に依存することはありません）。つまり、`Person` （または他のモデル）をすべて自分の作成したものに置き換えるための方法ではありません。

#### 基底クラスの制限

プロキシモデルは、ちょうど1つの非抽象モデルクラスを継承しなければなりません。プロキシモデルは異なるデータベースのテーブル上の行の間にコネクションを作らないため、複数の非抽象クラスを継承することはできません。一方、プロキシモデルは、モデルフィールドを定義して いない 限り、抽象モデルクラスをいくつでも継承できます。また、プロキシモデルは、共通の非抽象な親クラスを持つプロキシモデルをいくつでも継承できます。

#### プロキシモデルマネージャー

プロキシモデル上にモデルのマネージャーを定義しない場合、そのプロキシモデルはマネージャーを親のモデルから継承します。プロキシモデル上にマネージャーを定義した場合は、親クラス上のマネージャーで定義されて利用可能な物があったとしても、定義したほうのマネージャーがデフォルトになります。

先ほどの例の続きで、`Person` モデルにクエリを発行するときに使うデフォルトのマネージャを次のように変更できます：

    from django.db import models

    class NewManager(models.Manager):
        # ...
        pass

    class MyPerson(Person):
        objects = NewManager()

        class Meta:
            proxy = True

既存のデフォルトのマネージャを置き換えることなく、新しいマネージャをプロキシに追加したい場合は、 カスタムマネージャ で説明したテクニックを使用できます。新しいマネージャを含む基底クラスを作成し、それを主要な基底クラスの後に多重継承します：

    # Create an abstract class for the new manager.
    class ExtraManagers(models.Model):
        secondary = NewManager()

        class Meta:
            abstract = True

    class MyPerson(Person, ExtraManagers):
        class Meta:
            proxy = True

これが必要になることはあまりないでしょうが、必要であれば上記のような実装も可能です。

#### プロキシモデルの継承と管理対象外モデルの違い

プロキシモデルの継承は、あるモデルの `Meta` クラスにおける `managed` 属性を用いて Django に管理されないモデルを作成するのにかなり似ています。

`Meta.db_table` を慎重に設定することで、既存のモデルを隠ぺいする管理対象外モデルを作成し、その既存モデルに Python メソッドを追加できます。しかし、この方法では変更を加えたときに両方のモデルを同期する必要があるため、とても冗長で変更に弱いものとなります。

一方、プロキシモデルは、プロキシ対象となるモデルと全く同じように動作することを意図しています。プロキシモデルは親モデルのフィールドとマネージャを直接継承しているため、常に親モデルと同期します。

原則としては:

1. もし既存のモデルやデータベースのテーブルを反映したいが元となるテーブルのカラムの全てを必要とする訳ではない場合は、 `Meta.managed=False` を利用してください。このオプションはデータベースのビューやテーブルを Django の管理下に置きたくない場合に通常有用となります。

2. モデルの Python 上の振る舞いだけを変更したいが、元のモデルと同じフィールドをすべて保持したい場合は、`Meta.proxy=True` を使用します。これにより、データが保存される際にプロキシモデルが元のモデルのストレージ構造の正確なコピーとなるように設定されます。

### 多重継承

Python のサブクラス化と同様に、Django モデルも複数の親モデルを継承することが可能です。ただし、通常の Python の名前解決ルールが適用される点に注意してください。ある名前 (例えば Meta) が最初に登場する基底クラスが使用されます。たとえば、複数の親クラスに Meta クラスが含まれている場合、最初のものだけが使用され、それ以降のものは無視されます。

通常、複数の親クラスを継承する必要はありません。これが有用となる主なケースは、「ミックスイン (mixin)」クラスを使う場合です。ミックスインを使うと、すべての子クラスで特定の追加フィールドやメソッドを利用できます。ただし、継承階層はできるだけシンプルで分かりやすく保つようにしてください。そうすることで、特定の情報がどこから来ているのかを把握するために苦労せずに済みます。

共通の `id` 主キーフィールドを持った複数のモデルを継承すると例外が送出されることに注意してください。多重継承を正常に使うために、基底モデル内で明示的に `AutoField` を利用できます。

    class Article(models.Model):
        article_id = models.AutoField(primary_key=True)
        ...

    class Book(models.Model):
        book_id = models.AutoField(primary_key=True)
        ...

    class BookReview(Book, Article):
        pass

あるいは、共通の祖先を使って `AutoField` を保持します。このためには、以下のように、自動生成されて子に継承されたフィールド間の衝突を避けるために、各親モデルから共通の祖先への `OneToOneField` を明示的に使用する必要があります。

    class Piece(models.Model):
        pass

    class Article(Piece):
        article_piece = models.OneToOneField(
            Piece, on_delete=models.CASCADE, parent_link=True
        )
        ...

    class Book(Piece):
        book_piece = models.OneToOneField(Piece, on_delete=models.CASCADE, parent_link=True)
        ...

    class BookReview(Book, Article):
        pass

### フィールド名の「隠ぺい」は許可されない

通常の Python のクラス継承では、親クラスから継承したあらゆる属性を子クラスがオーバーライドできます。Django では、この挙動は通常モデルのフィールドに対して許容されません。もし非抽象なモデルの基底クラスが `author` フィールドを持っていたとしたら、そのモデルの基底クラスを継承したあらゆるモデルクラス内では `author` という名称の属性値を別のモデルのフィールドや属性として定義できなくなります。

この制約は抽象モデルを継承したモデルのフィールドに対しては適用されません。こういったフィールドは別のフィールドや値によってオーバーライドされるか `field_name = None` を設定することで削除する事ができます:

警告

モデルマネージャーは抽象基底クラスより継承されます。継承された `Manager` から参照される継承されたフィールドをオーバーライドすると、ちょっとしたバグを発生させることがあります。詳細は カスタムマネージャーとモデルの継承 を参照ください。

注釈

ある種のフィールドはモデル上に特別な属性を定義します、例えば `ForeignKey` は `_id` がフィールド名に付与された属性を、外部モデル上の `related_name` と `related_query_name` と同じように定義します。

これらの特別な属性はその属性を定義しているフィールドが、もはやその特別な属性を定義しなくなるように、変更もしくは削除されなければオーバーライドできません。

親モデルのフィールドをオーバーライドする事はインスタンス (どのフィールドが初期化されるか `Model.__init__` に定義している) の初期化やシリアライズ時の問題につながります。これらは通常の Python のクラス継承で全く同様に扱う事が求められていない機能であるため、 Django のモデル継承と Python のクラス継承のこうした差異は恣意的な設計による物ではありません。

この制限は `Field` のインスタンスである属性にのみ適用されます。通常の Python の属性は必要に応じてオーバーライドできます。また、この制限は Python が認識する属性名にだけ適用されます。データベースのカラム名を手動で設定している場合は、マルチテーブル継承の関係にある子と祖先のモデルで同じカラム名を使えます（2つのカラムは別のデータベーステーブル内にあるからです）。

もし祖先モデルのいずれかに定義されたモデルのフィールドをオーバーライドした場合 Django は `FieldError` 例外を送出します。

クラス定義中のフィールドの解決方法のため、複数の抽象親モデルから継承されたモデルのフィールドは、厳密な深さ優先順序で解決されることに注意してください。これは標準の Python の MRO とは対照的です。MRO では、ダイヤモンド型継承の場合には、幅優先で解決されます。この違いの影響を受けるのは複雑なモデル階層のみであり、これは（上記のアドバイスに従って）避けるべきです。

## パッケージ化したモデルを扱う

`manage.py startapp` コマンドを実行することで `models.py` ファイルを含むアプリケーション構造が作成されます。多数のモデルが存在する場合、それらを別のファイルとして管理するのが良いかもしれません。

それを行うため、 `models` パッケージを作成します。 `models.py` を削除してモデルを保持するための `__init__.py` ファイルを持つ `myapp/models/` ディレクトリを作成します。作成した `__init__.py` でモデルをインポートする必要があります。

例えば、 `organic.py` および `synthetic.py` を `models` ディレクトリ内に持っている場合:

`myapp/models/__init__.py`

    from .organic import Person
    from .synthetic import Robot

`from .models import *` という記述を用いずに各モデルを明示的にインポートする方法には名前空間を汚染しない、可読性を向上させる、コード解析ツールを有用な状態に保つという利点があります。

参考

モデルの手引き

  モデルのフィールド、関連オブジェクト、`QuerySet` を含む、モデルに関係するすべての API について説明しています。