# Django 5.0.9.dev20240806133106 ドキュメント

# モデル

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

基本:

- モデルは各々 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)

  さらに他の例は model field リファレンス で見ることができます。

  Changed in Django 5.0:

  マッピングと callable のサポートが追加されました。

`default`
  そのフィールドのデフォルト値です。このオプションには特定の値または呼び出し可能オブジェクトを渡すことができます。呼び出し可能オブジェクトの場合、新しくオブジェクトが生成される度に呼び出されます。
`help_text`
  フォームウィジェットとともに表示される追加の「ヘルプ」テキストです。この値はフィールドがフォームとして利用されない場合でもドキュメントとして役に立ちます。
`primary_key`

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

  定義したモデル内でどのフィールドに対しても `primary_key=True` が設定されなかった場合、Django は自動的に主キーを保存するために `IntegerField` を追加します、つまり、その主キーに対するデフォルトの動作を変更する必要がない場合は、どのフィールドに対しても `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` の 3 つを除いた各フィールドは、任意の第 1 引数を取ります -- 詳細な (verbose) 名前です。詳細な名前を与えない場合、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 が自動的に変換します。

### リレーション

リレーショナルデータベースの強力さがテーブル同士の関係によって決まることは疑いがありません。Dango では、最も一般的な 3 つのデータベースリレーションシップを定義しています: 多対 1、多対多、1 対 1 です。

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

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

`ForeignKey` には位置引数が必要です: モデルと関係させるクラスです。

たとえば、`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` インスタンスは、フォームで編集されるオブジェクトの側にあります。上の例では、 `toppings` は `Pizza` の中にあります (`Topping` が `pizzas` の `ManyToManyField` を持つとするよりはそのほうがいいでしょう)。というのは、ピザが複数のトッピングを持つほうが、トッピングが複数のピザの上にあるというよりも自然だからです。このようにすることで、ユーザは `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)

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

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

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

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

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. 同様の理由で、フィールド名の最後をアンダースコアにすることはできません。

しかし、これらの制約を回避する手段はあります。なぜなら、フィールド名は必ずしもデータベースのカラム名と一致する必要はないからです。詳細については `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 は、モデルのインスタンスを文字列で表示する必要に迫られたときにこれを使います。特に、オブジェクトをインタラクティブコンソール内や admin 内で表示する際に該当します。

  このメソッドは常に指定することを推奨します; デフォルトはあまり役に立つものではありません。

`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, *args, **kwargs):
            do_something()
            super().save(*args, **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, *args, **kwargs):
            if self.name == "Yoko Ono's blog":
                return  # Yoko shall never have her own blog!
            else:
                super().save(*args, **kwargs)  # Call the "real" save() method.

スーパークラスのメソッドを呼び出し忘れないようにすることが重要です -- `super().save(*args, **kwargs)` のことです -- これでオブジェクトがデータベースに保存されることが保証されます。スーパークラスのメソッドを呼び出し忘れると、デフォルトの動作は発生せずデータベースは変更されません。

モデルのメソッドに引数を渡すこともまた重要です -- `*args, **kwargs` が行います。Django は、しばしばビルトインのモデルメソッドの機能を拡張するため、新しい引数を追加します。自分で記述したメソッド定義内に `*args, **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, force_insert=False, force_update=False, using=None, update_fields=None
        ):
            self.slug = slugify(self.name)
            if update_fields is not None and "name" in update_fields:
                update_fields = {"slug"}.union(update_fields)
            super().save(
                force_insert=force_insert,
                force_update=force_update,
                using=using,
                update_fields=update_fields,
            )

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

オーバーライドされたモデルメソッドはバルク操作では呼ばれません

オブジェクトの `delete()` メソッドは、QuerySet を使用したオブジェクトの一括削除 や `カスケード削除` を行ったときに、必ずしも呼ばれるわけではないことに注意してください。カスタマイズされた削除ロジックが実行されることを保証するためには、`pre_delete` と `post_delete` シグナルのいずれかまたは両方が利用できます。

残念ながら、オブジェクトを一括で `作成` または `更新` するときにはワークアラウンドはありません。この場合には `save()`、`pre_save`、`post_save` のいずれも呼ばれないためです。

### カスタムの 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 クラスに対して 1 つの調整を行います: 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` となります。 `'%(class)s'` と `'%(app_label)s'` の箇所をどのように利用して related name あるいは related query name を作るのかは任意で決められますがもしこれらを利用することを忘れた場合、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` 例外が発生します。

`Place` にリンクする `Restaurant` 上に自動的に生成された `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 = []

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

複数テーブルの継承は親モデルと子モデルの関連付けに暗黙的な `OneToOneField` を利用するため、先の例で示されたように、親から子に情報を移動させることは可能です。しかしその関連付けには `ForeignKey` および `ManyToManyField` に付与されたデフォルトの `related_name` の値を利用します。もしこの種類の関連付けを親モデルのサブクラスに対して用いる場合、 `related_name` 属性を各フィールドに 定義しなければなりません 。もし設定を忘れれば、Django はバリデーション例外を送出します。

例として、上で用いた `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 はリクエストされたモデルを返し続ける

`Person` オブジェクトに対して問い合わせた場合に Django に、あえて言えば、 `MyPerson` オブジェクトを返させる事はできません。プロキシオブジェクトのポイントはオリジナルの `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 クラスを含んでいる場合、最初のもののみが使用され、他のすべては無視されることを意味します。

通常は複数の親モデルを継承する必要はありません。この機能が有用な主な状況はクラスの "ミックスイン"（そのクラスを継承する全てのクラスに特別なフィールドやメソッドを追加させる技術）を利用する場合です。継承階層をできるだけシンプルで直接的に保つようにして、特定の情報がどこから来ているのかを把握するための苦労をすることのないないようにしてください。

共通の `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 について説明しています。