モデル API リファレンス

revision-up-to:8001 (1.0pre SVN)

モデルとは、サイトを構成するデータの、ただ一つかつ最終的なデータソースを指 します。モデルには、保存したいデータに不可欠なデータフィールドと、その振舞 いが収められています。一般的に、各モデルは単一のデータベーステーブルに対応 づけられています。

基本として、まず以下のことを知っておきましょう:

  • 各モデルは Python のクラスで、 django.db.models.Model のサブクラ スになります。
  • モデルの各属性値は、データベース上のあるフィールドを表現します。
  • モデルのメタデータ (フィールドで表現されない情報) は Meta と呼ば れる内部クラスに配置します。
  • これらの情報をもとに、 Django はデータベース API を自動生成します。 API については データベース API リファレンス で解説します。

このドキュメントを理解する上で、 モデル例の公式リポジトリ が参考になるでしょう。 (Django のソース配布物中では、これらの例は tests/modeltests ディレクトリに収められています。)

簡単な例

以下のモデル例では、 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_namelast_name はモデルの フィールド (fields) です。各 フィールドはクラス属性として定義され、各属性がデータベースのカラムに対応し ます。

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

CREATE TABLE myapp_person (
    "id" serial NOT NULL PRIMARY KEY,
    "first_name" varchar(30) NOT NULL,
    "last_name" varchar(30) NOT NULL
);

以下に技術的な注意点を示します:

  • テーブルの名前、 myapp_person はモデルのメタデータから自動的に導 出したものですが、オーバライドもできます。後述の テーブル名 を参照 してください。
  • id は自動的に追加されますが、この挙動もまたオーバライドできます。 自動的な主キーフィールド を参照してください。
  • この例の CREATE TABLE SQL 文は PostgreSQL の書式で書かれています が、 Django は 設定ファイル に指定されたデータベースバックエンド向 けの SQL を使います。

フィールド

モデルで最も重要であり、かつモデル定義で最小限必要な部分は、モデル内が定義 しているデータベースフィールドのリストです。フィールドはクラスの属性として 定義されています。

例を示します:

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)
    name = models.CharField(max_length=100)
    release_date = models.DateField()
    num_stars = models.IntegerField()

フィールド名の制約

Django がモデルのフィールド名に課している制約は二つしかありません:

  1. フィールド名は Python の予約語であってはなりません。さもなければ Python のシンタクスエラーを引き起こすからです。例えば:

    class Example(models.Model):
        pass = models.IntegerField() # 'pass' は予約語です!
    
  2. フィールド名には二つ以上の連続するアンダースコアを入れてはなりません。 なぜなら、Django のクエリ照合構文で使われているからです。例えば:

    class Example(models.Model):
        foo__bar = models.IntegerField()  # 'foo__bar' に '__' が入っています!
    

フィールドの名前は必ずしもデータベースのカラム名と一致していなくてもよいの で、これらの制約は回避可能です。詳しくは後述の db_column を参照してくだ さい。

joinwhere, select のような SQL の予約語は、モデルのフィール ド名に使っても かまいません 。というのも、Django はいかなる SQL クエリ文 でも全てのデータベーステーブル名やカラム名をエスケープするからです。エスケー プにはデータベースエンジン固有のクオートシンタクスを使います。

フィールドのタイプ

モデルの各フィールドは適切な Field クラスのインスタンスにせねばなりませ ん。 Django はフィールドクラス型を以下のいくつかの判定に使います:

  • データベースのカラム型 (INTEGER, VARCHAR など)。
  • Django の admin サイトで使うウィジェットの選択 (<input type="text">, <select> など)。
  • Django の admin やマニピュレータで使われている最小限の検証 (validation)。

使えるフィールド型は以下の通りです。

AutoField

IntegerField の一種で、利用可能な ID の中から自動的にインクリメントして いきます。通常、このフィールドが直接必要になることはないでしょう。主キーの フィールドは、特に指定しない限り自動的に追加されます。 自動的な主キーフィールド を参照してください。

BooleanField

真偽 (true/false) 値を表すフィールドです。

admin ではこのフィールドはチェックボックスとして表現されます。

CharField

文字列フィールドで、短い文字列からやや長いものに適しています。

大量のテキストを入れたい場合には TextField を使って下さい。

admin では <input type="text"> (一行の入力フィールド) で表現されます。

CharField には max_length という必須の引数があります。この引数はフィー ルドの (文字数で表した) 最大長です。 max_length への制約はデータベースと Django 内の検証の両方のレベルで行われます。

ベテラン Django ユーザへの注意: Django 内での一貫性を持たせるため、 引数名 maxlengthmax_length に変わりました。これまで通り maxlength 引数は使えますが、今後は max_length を使うよう勧めます。

CommaSeparatedIntegerField

カンマで区切った整数からなるフィールドです。 CharField と同じく、 max_length 引数が必要です。

DateField

日付フィールドです。オプションの引数がいくつかあります:

引数 説明
auto_now オブジェクトを保存する度に、その時の時刻を自動的に設 定します。 "last-modified" タイムスタンプの実現に便 利です。この値はオーバライドできるデフォルト値ではな く、 常に 現在の日付になるので注意してください。
auto_now_add オブジェクトを生成した時の時刻を自動的に設定します。 タイムスタンプの生成に便利です。この値はオーバライド できるデフォルト値ではなく、 常に 現在の日付になる ので注意してください。

admin では、 JavaScript のカレンダーと 「今日」へのショートカットのついた <input type="text"> として表現されます。 JavaScript カレンダーは常に 日曜日から週が始まります。

DateTimeField

日付と時刻のフィールドです。 DateField と同じオプションを取ります。

admin では JavaScript のショートカットのついた <input type="text"> フィールドで表現されます。

DecimalField

開発版の Django で新たに追加された機能です

固定精度の 10 進小数です。 Python の Decimal 型インスタンスとして表現さ れます。 必須の 引数が 2 つあります:

引数 説明
max_digits 値を表現するのに使える最大桁数です。
decimal_places 小数部の保存に使われる桁数です。

例えば、小数部が 2 桁で、 999 までの数を表現できるようなフィールドを作成す るには、以下のようにします:

models.DecimalField(..., max_digits=5, decimal_places=2)

小数部の精度が 10 桁で、 10 億までの数を表現できるようにしたければ、以下の ようにします:

models.DecimalField(..., max_digits=19, decimal_places=10)

admin では、 <input type="text"> (一行のテキスト入力) で表現されます。

EmailField

値が有効な e-mail アドレスであるかチェックする CharField です。

Django 0.96 では、 max_length を指定できません。 max_length は自動的に 75 にセットされるからです。 開発版の Django では、 max_length はデフォルト で 75 にセットされますが、デフォルト値を書き換えるよう指定することができます。

FileField

ファイルアップロードのためのフィールドです。 必須の 引数を一つ持ちます:

引数 説明
upload_to ローカルのファイルシステム上のパスです。 このパスは MEDIA_ROOT に設定したパスの後ろに つけられ、 get_<fieldname>_url() ヘルパ関数 の出力を決める際に使われます。

パスには strftime によるフォーマット を入れてもかまいません、フォーマッ ト文字列が入っていれば、(ディレクトリが同名のアップロードファイルで埋まらな いように)ファイルのアップロード日時に置き換わります。

admin では、 <input type="file"> (ファイルアップロードウィジェット) で表現されます。

モデル中で FileFieldImageField (下記参照) を使うには、以下のよう なステップが必要です:

  1. Django にアップロードされたファイルを保存させたい場所のフルパス を設定ファイル中の MEDIA_ROOT に指定します。(パフォーマンス 上の理由から、アップロードされたファイルはデータベースに保存され ません。) 保存場所への公開 URL を MEDIA_URL に指定します。 ディレクトリは Web サーバのユーザアカウントによって書き込み可能 であるか確認してください。
  2. FileFieldImageField をモデルに定義します。このとき、 upload_to オプションを指定して、 MEDIA_ROOT 下のサブディ レクトリのどこにアップロードされたファイルを置くべきかを Django に教えます。
  3. データベースに保存されるのはファイルへのパス (MEDIA_ROOT か らの相対) です。Django の提供している get_<fieldname>_url 関 数を使うことになるでしょう。例えば、 mug_shot という名前の ImageField があれば、画像への絶対 URL は {{ object.get_mug_shot_url }} で取得できます。

例えば、 MEDIA_ROOT'/home/media' にして、 upload_to'photos/%Y/%m/%d' に設定したとします。 upload_to'%Y/%m/%d' の部分は strftime と同じフォーマット文字を使っています。すなわち、 '%Y' が 4 桁の年号、 '%m' が 2 桁の月、 '%d' が 2 桁の日を表します。 従って、ファイルを 2007 年の 1 月 15 日にアップロードすると、 /home/media/photos/2007/01/15 に保存されることになります。

アップロードファイルのディスク上でのファイル名を取得したい場合や、ファイル にアクセスするための URL を調べたい場合、ファイルのサイズを知りたい場合は、 それぞれ get_FOO_filename(), get_FOO_url(), get_FOO_size() メソッドを使えます。詳しくは get_FOO_ メソッド の説明を参照してください。

ファイルのアップロードを処理するときには、常にアップロード先の場所やアップ ロードされるファイルに注意して、セキュリティホールを避けるようにしてくださ い。 アップロードされる全てのファイルをチェックして 、予想外のファイルが アップロードされないようにしましょう。例えば、バリデーションを行わずに Web サーバのドキュメントルート下へのファイルのアップロードを盲目的に受け入れる と、そこに誰かが CGI や PHP スクリプトをアップロードして、あなたのサイト上 の URL を訪問した人にスクリプトを実行させられてしまいます。そんなことを許し てはなりません。

開発版の機能です: デフォルトでは、 FileField インスタンスは varchar(100) カラムをデータベースに作成します。他のフィールドにしたければ、 max_length 引数を使って最大長を変更することができます。

FilePathField

ファイルシステム上のあるディレクトリ下のファイル名だけを選べるようになって いるフィールドです。 3 つの特別な引数があり、そのうち最初の一つは 必須 です:

引数 説明
path 必須です。 FilePathField が選択肢を作成するための ディレクトリへの絶対パスです。例: "/home/images"
match オプションです。正規表現を表す文字列で、 FilePathField がファイル名のフィルタに使います。正 規表現はフルパスではなくファイル名に適用されるので注意 してください。 例: "foo.*\.txt$"foo23.txt にはマッチしますが、 bar.txtfoo23.gif には マッチしません。
recursive オプションです。 True または False です。デフォ ルトは False で、 path のサブディレクトリを含め るかどうかを指定します。

もちろん、これらの引数を組み合わせて使ってもかまいません。

よくある勘違いは、 match がファイル名ではなくフルパスに適用されると思っ てしまうことです。以下の例:

FilePathField(path="/home/images", match="foo.*", recursive=True)

/home/images/foo.gif にはマッチしますが、ファイル名本体 (foo.gifbar.gif) にマッチするため、 /home/images/foo/bar.gif にはマッチ しません。

開発版の機能です: デフォルトでは、 FilePathField インスタンスは varchar(100) カラムをデータベースに作成します。他のフィールドにしたければ、 max_length 引数を使って最大長を変更することができます。

FloatField

開発版の Django で仕様が変更されました。

浮動小数点数です。Python の float 型インスタンスで表現されます。

admin では、 <input type="text"> (一行の入力フィールド) で表現されます。

NOTE: 開発版の Django では、 FloatField の仕様が変更されています。 以前の仕様は、 Django 0.96 のドキュメント を参照してください。

ImageField

FileField に似ていますが、アップロードされたオブジェクトが有効なイメー ジかどうか検証します。二つのオプション引数、 height_field および width_field をとり、これらの値が設定されている場合には、モデルのインス タンスを保存するときに画像の高さと幅も同時に保存します。

ファイルフィールドで使える get_FOO_* メソッドの他に、 ImageField で は get_FOO_height() および get_FOO_width() メソッドを使えます。詳し くは get_FOO_height() と get_foo_width() の説明 を参照してください。

Python Imaging Library が必要です。

開発版の機能です: デフォルトでは、 ImageField インスタンスは varchar(100) カラムをデータベースに作成します。他のフィールドにしたければ、 max_length 引数を使って最大長を変更することができます。

IntegerField

整数です。

admin では、 <input type="text"> (一行の入力フィールド) で表現されます。

IPAddressField

IP アドレスを 文字列形式で表したもの (例: "192.0.2.30") です。

admin では、 <input type="text"> (一行の入力フィールド) で表現されます。

NullBooleanField

BooleanField と, 同じですが、 NULL を選択肢に使えます。 null=TrueBooleanField の代わりに使って下さい。

admin では、「不明」 ("Unknown") 「はい」 ("Yes")、「いいえ」 ("No") の選択 肢をもつ <select> ボックスで表現されます。

PhoneNumberField

CharField と同じですが、値がアメリカ形式の電話番号として有効な形式 (XXX-XXX-XXXX) かどうかをチェックします。

PositiveIntegerField

IntegerField と同じですが、正の数でなければなりません。

PositiveSmallIntegerField

PositiveIntegerField と同じですが、ある範囲以下 (データベース依存です) の値しか使えません。

SlugField

「スラグ (slug)」は新聞業界の用語で、内容を示す短いラベルです。スラグは文字、 数字、アンダースコア、ハイフンだけからなります。スラグはよく URL に使 われます。

CharField と同様、 max_length を指定できます。指定しなかった場合、 Django はデフォルト値の 50 を使います。 db_index=True になります。

SmallIntegerField

IntegerField と同様ですが、ある範囲以下 (データベース依存です) の値しか 使えません。

TextField

長いテキストのためのフィールドです。

admin では、 <textarea> (複数行の入力フィールド) で表現されます。

TimeField

時刻です。 DateFieldDateTimeField と同じく、自動的に値を埋めるた めのオプションを使えます。

admin では、JavaScript のショートカットがついた <input type="text"> で 表現されます。

URLField

URL を表すフィールドです。 verify_exists オプションを True (デフォ ルト値です) にすると、指定された URL が実在する (URL は実際にロードでき、か つ 404 応答を返さない) かどうか検証します。

admin では、 <input type="text"> (一行の入力フィールド) で表現されます。

URLField にはオプションの引数として、フィールドの最大長 (文字数) を表す max_length を指定できます。 max_length はデータベースのレベルや Django のバリデーションで自動的に指定されます。 max_length を指定しない ときのデフォルトの値は 200 です。

USStateField

2 文字のアメリカ合衆国州名略号です。

admin では、 <input type="text"> (一行の入力フィールド) で表現されます。

XMLField

TextField と同様ですが、指定されたスキーマに従って、値が有効な XML であ るか検証します。 schema_path を必須の引数にとります。 schema_path は検証に使う RelaxNG スキーマを指すファイルシステム上のパス名です。

フィールドのオプション

全てのフィールド型で、以下の引数を指定できます。これらの引数はすべてオプショ ンです。

null

True にすると、 Django は空の値を NULL としてデータベースに入れます。 デフォルト値は False です。

空の文字列値は NULL ではなく空文字列として保存されることに注意して下さ い。 null=True が使えるのは、整数型やブール型、日付のような、文字列では ないフィールド型の場合だけです。 null はデータベースでの記録操作にのみ かかわるパラメタなので、フォーム上で空の値を入力できるようにしたければ blank=True も指定する必要があるでしょう (blank については後で述べます)。

特別な理由のない限り、 CharFieldTextField のような、文字列ベース のフィールドには null を指定しないようにしてください。文字列ベースのフィー ルドが nill=True であるということは、「データがない」ことを表すのに NULL と空文字列という二つの値が存在することを示します。多くの場合、「デー タがない」ことを表すのに二つのを取り得るのは冗長でしかありません。 Django の慣習では、データのない文字列フィールドの値は NULL ではなく空文字列で す。

Note

Oracle バックエンドを使っている場合、データベースの制約のため、 空文字列を許すような文字列ベースのフィールドは、 null=True オプション が強制的に付加され、 NULL が空の文字列を指すようになります。

blank

True にすると、フィールドの値を空白 (blank) にできます。デフォルト値は True です。

null とは違うことに注意してください。 null が純粋にデータベース上の 表現に関わる概念であるのに対し、 blank とは値の検証 (validation) に関わ る概念です。あるフィールドに blank=True を指定すると、 Django の admin サイト上で、空の値のエントリを作れるようになります。 blank=False にする と、そのフィールドには必ず値を入れねばなりません。

choices

2 要素のタプルからなる iterable (リストまたはタプル) を、フィールドの値の選 択肢にします。

この値を指定すると、 Django の admin には標準的なテキストフィールドの代わり に選択ボックスが表示され、指定された選択肢だけをえらべるようになります。

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

YEAR_IN_SCHOOL_CHOICES = (
    ('FR', 'Freshman'),
    ('SO', 'Sophomore'),
    ('JR', 'Junior'),
    ('SR', 'Senior'),
    ('GR', 'Graduate'),
)

各タプルの最初の要素は、データベースに実際に保存される値です。二つ目の値は 各オプションに対する人間可読な名前です。

選択肢リストは、モデルクラスの一部として定義できます:

class Foo(models.Model):
    GENDER_CHOICES = (
        ('M', 'Male'),
        ('F', 'Female'),
    )
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

また、モデルクラスの外でも定義できます:

GENDER_CHOICES = (
    ('M', 'Male'),
    ('F', 'Female'),
)
class Foo(models.Model):
    gender = models.CharField(max_length=1, choices=GENDER_CHOICES)

また、選択肢をグループごとに集めて、名前をつけられます:

MEDIA_CHOICES = (
    ('Audio', (
            ('vinyl', 'Vinyl'),
            ('cd', 'CD'),
        )
    ),
    ('Video', (
            ('vhs', 'VHS Tape'),
            ('dvd', 'DVD'),
        )
    ),
    ('unknown', 'Unknown'),
)

各タプルの最初の要素は、選択肢グループの名前です。二つ目の要素は、2 要素の タプルからなるイテレーション可能なオブジェクトです。各 2 要素タプルには、 選択肢の値と、人間可読な名前を指定します。(上の例の unknown オプション のように) グループ化されたオプションとされていないオプションを混ぜても構い ません。

choices セットを持つモデルフィールド各々について、 Django は特殊なメソッ ドを追加し、フィールドの現在値を人間可読な形式で取得できるようにします。デー タベース API ドキュメントの get_FOO_display を参照してください。

最後に、 choices はリストやタプルでなくてもよく、任意の iterable オブジェク トでかまわないことに注意してください。つまり、 choices は動的生成できるので す。とはいえ、 choices を動的生成するようなハックをするくらいなら、適当 なデータベーステーブルを ForeignKey で参照した方がよいでしょう。 というのも、 choices はあまり変更のない静的な選択肢のためのオプションだ からです。

core

オブジェクトが他のオブジェクトからリレーションを張られていて、インライン編 集の対象であるときに、フィールドをコアデータとしてマークします。

Django の admin 上でインライン編集しているオブジェクトの "core" フィールド の値を全て消去すると、そのオブジェクトは削除されます。

インライン編集可能なリレーションには、 core=True であるフィールドが少な くとも一つ必要です。なければエラーになります。

"core" を指定したフィールドは、Django admin サイト上では必須のフィールドと して扱われるので注意してください。実質的には、インライン編集の対象になるよ うなオブジェクトの全てのフィールドに core=True を指定しておかねばなり ません。

db_column

フィールドに使うデータベースカラム名です。この値を指定しなければ、 Django はフィールド名を使います。

データベースカラム名が SQL の予約語であったり、 Python で変数名として使えな い文字を含んでいる (よくあるのはハイフンです) 場合でも問題ありません。 Django は必要に応じてカラム名やテーブル名をクオートします。

db_index

True にすると django-admin.py sqlindexes を実行した時に、フィールド に対して CREATE INDEX 文を出力します。

db_tablespace

開発版の Django で新たに追加された機能です

このフィールドをインデクス化する際に、データベースのテーブルスペース上での フィールドのインデクスの名前に使います。デフォルトの値は、プロジェクトで 設定されている DEFAULT_INDEX_TABLESPACE です。この値がなければ、 モデルの db_tablespace を使います。テーブルスペースをサポートしていない バックエンドでは、このオプションは無視されます。

default

フィールドのデフォルト値です。この値は、何らかの値でも、呼び出し可能オブジェ クトでもかまいません。呼び出し可能オブジェクトの場合、新たなオブジェクトが 生成されるたびに呼び出されます。

editable

False にすると、 admin 上や、オブジェクトの AddManipulator および ChangeManipulator クラスを使ったフォーム処理でフィールドの値を編集でき なくなります。デフォルト値は True です。

help_text

オブジェクトの admin フォームの下に表示される、追加の「ヘルプ」テキストです。 とはいえ、オブジェクトが admin のフォームを持っていなくてもドキュメントとし て有用でしょう。

この値は admin インタフェース上に表示されるときに HTML エスケープされ ない ので注意してください。必要ならば、下記の例のように help_text に HTML を含めてもかまいません:

help_text="<em>YYYY-MM-DD</em> の形式で記入してください。"

primary_key

True に指定すると、フィールドをモデルの主キーにします。

モデルのどのフィールドにも primary_key=True を指定しなければ、Django は 自動的に以下のフィールドを追加します:

id = models.AutoField('ID', primary_key=True)

従って、デフォルトの主キーの振舞いを変更したいのでないかぎり、 primary_key=True をフィールドに指定しておく必要はありません。

primary_key=True であるということは、 null=False 、 かつ unique=True であることを指します。一つのオブジェクトには一つしか主キー を指定できません。

radio_admin

デフォルトでは、 ForeignKey のフィールドや choices の設定されたフィー ルドに対して、 Django の admin は選択ボックスインタフェース (<select>) を使 います。 radio_adminTrue にすると、 Django はラジオボタンのイン タフェースを使います。

フィールドが ForeignKey であるか、 choices が設定されている のでなければ、このオプションを指定してはなりません。

unique

True であれば、フィールドはテーブル全体で一意の値を取らねばなりません。

この制約は、データベースレベルと Django の admin のレベルで適用されます。 重複した値を持つ unique フィールドを含んだモデルを保存しようとすると、 モデルの save() メソッドによって django.db.IntegrityError が送出さ れます。

unique_for_date

DateFieldDateTimeField 型のフィールドの名前を指定しておくと、そ のフィールドの日付に対して一意な値になるように制約します。

例えば、 title という名前のフィールドがあり、 unique_for_date="pub_date" が指定されていたとすると、 Django は同じ titlepub_date の値を持つようなエントリを受け入れません。

この制約は Django の admin フォームのレベルで適用され、データベースレベルで は適用されません。

unique_for_month

unique_for_date と同様ですが、フィールドの値が月ごとに一意であるように 制約します。

unique_for_year

unique_for_dateunique_for_month と同様です。

validator_list

フィールドに適用する追加のバリデータ (検証機構) のリストです。各バリデータ は呼び出し可能オブジェクトで、引数に field_data, all_data を取り、エラー が生じたときには django.core.validators.ValidationError を送出するよう になっていなければなりません (バリデータのドキュメント) を参照してくださ い。

Django にはほんの少しだけバリデータがついてきます。バリデータは django.core.validators に収められています。

詳細なフィールド名

各フィールドの型は、 ForeignKey, ManyToManyField および OneToOneField を除き、オプションの固定引数 (positional argument) を第一 引数として指定できます。この引数には人間可読なカラム名を指定します。引数を 指定しなければ、 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 では、第一引数 は必須で、モデルのクラスにします。従って、人間可読なカラム名を指定するには、 verbose_name キーワード引数を使います:

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

慣習的に、 verbose_name の先頭の文字は大文字にしないことになっています。 Django は必要なときに先頭の文字を自動的に大文字にします。

リレーション

関係データベースの威力はテーブルを相互に関連づけることにあるのはいうまでも ありません。Django ではよく使われるデータベースリレーション (relationship)、 多対一 (many-to-one)、多対多 (many-to-many)、一対一 (one-to-one) を定義する 方法を提供しています。

多対一のリレーション

多対一のリレーションを定義するには ForeignKey を使います。このフィール ドは他のフィールド型と同じように、モデルのクラス属性に含めて使えます。

ForeignKey には、固定引数が一つあり、リレーションを張る対象のクラスを 指定します。

例えば、 Car モデルに Manufacturer というフィールドを持たせたいとし ましょう。すなわち、ある Manufacturer には複数の Car が対応するが、 各 Car には一つだけ Manufacturer が対応するようにしたいとしましょう。 この場合、以下のように定義します:

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

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

再帰的なリレーションを張る、つまり自分自身への多対一のリレーションを張る場 合には、 models.ForeignKey('self') を使います。

未定義のモデルへのリレーションを作成した場合、モデルオブジェクトではなくモ デルの名前も使えます:

class Car(models.Model):
    manufacturer = models.ForeignKey('Manufacturer')
    # ...

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

開発版の Django で新たに追加された機能: 他のアプリケーションで定義され ているモデルを参照したければ、アプリケーションラベルを明示的に指定せねばな りません。例えば、上の例の Manufacturer モデルが、 production とい う別のアプリケーションで定義されているのなら、以下のように書かねばなりませ ん:

class Car(models.Model):
    manufacturer = models.ForeignKey('production.Manufacturer')

舞台裏では、 Django はフィールド名に "_id" をつけた名前でデータベースのカラ ム名を生成します。上の例では、 Car モデルのデータベーステーブルには manufacturer_id カラムが入ります (このカラム名は db_column を明示的 に指定して変更できます。詳しくは db_column を参照してください) 。とはい え、カスタムのSQL 文を発行するのでないかぎり、データベースのカラム名をコー ドで直接扱う必要はありません。

必須ではありませんが、 ForeignKey の名前 (上の例では manufacturer) は、モデル名を小文字にしたものにするよう勧めます。もちろん好きな名前を付け てもかまいません。例えば:

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

完全な使用例は 多対一のリレーションを持つモデルの例 を参照してください。

ForeignKey フィールドはリレーションの動作を定義するための引数をいくつか とれます。これらは全てオプションです:

引数 説明
edit_inline True にすると、リレーション先のオブジェクト をリレーション元のオブジェクトのページで「イン ラインで」編集できます。これにより、リレーショ ン先のオブジェクトは独自の admin インタフェース を持たなくなります。 models.TABULAR または models.STACKED を指 定してください。それぞれ、インライン編集可能な オブジェクトをテーブルまたはスタックしたフィー ルドとして表示します。
limit_choices_to

admin で利用可能な選択肢を制限するための、ラベ ルと値を対応づけた辞書です (データベース API のリファレンス 参照)。 Python の datetime モジュールと組み合わせて、 オブジェクトを日付で制限できます。例えば:

limit_choices_to = {
   'pub_date__lte': datetime.now}

のようにすると、 pub_date が現在の日時より 前のオブジェクトしか選べなくなります。

より複雑なクエリを実現するために、辞書の代りに Q オブジェクト (get_sql() メソッドを備 えたオブジェクト) も指定できます。

edit_inline と互換性がありません。

max_num_in_admin

インライン編集オブジェクトを編集するときに、 リレーションの張られたオブジェクトを admin に 最大何個まで表示するかを指定します。例えば、 ピザに乗せられるトッピングを 10 個までに制限 したければ、 max_num_in_admin=10 とする ことで、ユーザに 10 個以上のトッピングを 入力させなくできます。

この制限では、リレーションの張られたオブジェク トを実際に 10 個以上生成できなくするわけでは ないので注意してください。この引数が制御して いるのは admin インタフェースだけで、 Python API レベルやデータベースレベルでは制限を課しま せん。

min_num_in_admin リレーションの張られたオブジェクトを admin に少なくとも何個表示するかを指定します。 通常、オブジェクトの生成ステージ (creation stage) では、 num_in_admin 個のインラインオブジェ クトが表示され、編集ステージ (edit stage) では 既存のオブジェクトに加えて num_extra_on_change 個の空白オブジェクトを 表示するようになっています。 ただし、リレーションの張られたオブジェクトの数 が min_num_in_admin 個以下の場合には表示 しません。
num_extra_on_change オブジェクトの変更ステージにおいて、追加のブラ ンクのフィールドを何個表示するかを指定します。
num_in_admin オブジェクトの追加ステージで、インラインオブジェ クトをデフォルトで何個表示するかを指定します。
raw_id_admin

ドロップダウンメニューの代わりに、整数を入力す るフィールドだけを表示します。

関連づけの対象になるオブジェクトの数が多すぎて 選択ボックスが実用的でない場合に便利です。

edit_inline とは組み合わせて使えません。

related_name

リレーション先のオブジェクトから逆参照するとき に使われる名前です。詳しくは オブジェクトのリレーションに関する解説 を参照してください。

抽象ベースクラス を使っているなら、 補足related_name に関する説明にも目を通して ください。

to_field リレーション先のオブジェクトの、リレーションを 張る対象のフィールド名です。デフォルトでは、 リレーション先のオブジェクトの主キーを使います。

多対多のリレーション

多対多の (many-to-many) リレーションを定義するには ManyToManyField を使います。このフィールドは他のフィールド型と同じように、モデルのクラス属 性に含めて使えます。

ManyToManyField には固定引数が一つあり、リレーションを張る対象のクラスを 指定します。

例えば、 Pizza には複数の Topping オブジェクトを持たせられます。 すなわち、ある Topping は複数のピザの上に置けて、逆にそれぞれのピザには 複数のトッピングを置けるというわけです。このリレーションを表すには次のように します:

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

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

ForeignKey と同じく、モデル名ではなく文字列 'self' を使えば自分自身 へのリレーションを定義できます。また、モデル名の入った文字列を使えば、未定 義のモデルも参照できます。ただし、文字列を使ってモデルを参照できるのは、同 じ models.py ファイル中にあるモデルだけです。別のアプリケーション中のモデル や、その他の場所から import したモデルは文字列で参照できません。

必須ではありませんが、 ManyToManyField の名前 (上の例では toppings) は、リレーション先のモデル名の複数形にするよう勧めます。

背後では、 Django は中間の join テーブルを生成して、多対多のリレーション を表現します。

どちらのモデルで ManyToManyField を定義してもかまいませんが、 どちらか片方のモデルにしか必要ありません -- 両方には指定できません。

一般的に、 Django の admin を使っている場合、 ManyToManyField インスタ ンスを入れておくのは、 admin インタフェースで編集される側のオブジェクトにし ておきます。上の例では、 topping は (ToppingManyToManyFieldpizzas をもたせるのではなく) Pizza に入れておきます。というのも、 「トッピングを乗せるピザ」と考えるよりも「ピザの上に乗せるトッピング」を考 える方が自然だからです。こうして上の例では、 Pizza の admin フォームで ユーザにトッピングを選ばせることになります。

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

ManyToManyField フィールドはリレーションの動作を定義するための引数を いくつかとれます。これらは全てオプションです:

引数 説明
related_name 前述の ForeignKey の説明を参照してください。
filter_interface ユーザビリティが紙一重の <select multiple> の代わりに、気の利いた控えめな Javascript の 「フィルタ」インタフェースを使います。値は models.HORIZONTAL または models.VERTICAL のいずれか (インタフェースを横ならびにするか縦 ならびするか) です。
limit_choices_to ForeignKey の同名オプションの説明を参照し てください。
symmetrical

自分自身への ManyToManyField を定義すると きにのみ使います。以下のようなモデルを考えます:

class Person(models.Model):
    friends = models.ManyToManyField("self")

Django がこのモデルを処理する際、自分自身に対 する ManyToManyField が定義されていること を認識して、 Person クラスに person_set 属性を追加しないようにします。 その代り、 ManyToManyField を対称的 (symmetrical) であるとみなします。すなわち、私 があなたの友達なら、あなたは私の友達である、と いうようにです。

self に対する ManyToMany の関係に対称 性を望まない場合は、 symmetricalFalse にしてください。これにより、 Django に逆参照用のデスクリプタを追加させ、 ManyToMany を非対称にできます。

db_table 多対多のリレーション情報を保存するために作成さ れるテーブルの名前です。名前を指定しなければ、 Django はデフォルトの名前を使います。デフォル トの名前は、結合する二つのテーブルの名前に基づ いて決められます。

一対一のリレーション

一対一のリレーションを定義するには、 OneToOneField を使います。 このフィールドは他のフィールド型と同じように、モデルのクラス属 性に含めて使えます。

このリレーションがもっとも有用なのは、あるオブジェクトが別のオブジェクト を何らかの形で「拡張」している場合の主キーとして使う場合です。

OneToOneField には固定引数が一つあり、リレーションを張る対象のクラスを 指定します。

例えば、「場所 (place)」のデータベースを作るときには、アドレス、電話番号、 といった標準的なものを作成します。その上で、レストランデータベースを作成 するときに、 Restaurant モデルの中に同じフィールドをつくるような 繰り返し作業 (repeat yourself) をする代わりに、場所データベースを基盤にして レストランのデータベースを作成したいとしましょう。このとき、 Restaurant には Place への OneToOneField をもたせられます (レストランは 場所に対して "is-a" の関係だからです)

ForeignKey と同じく、モデル名ではなく文字列 'self' を使えば自分自身 へのリレーションを定義できます。また、モデル名の入った文字列を使えば、未定 義のモデルも参照できます。

OneToOneField は以下のオプションを指定できます:

引数 説明
parent_link

他のモデルを継承しているモデル中で True に すると、子のクラスのインスタンスから親のクラスの インスタンスに向けたリンクのフィールドとして 使います。詳しくは モデルの継承 を参照してくださ い。

開発版の Django で新たに追加された機能です

開発版の Django で新たに追加された機能: 以前は、モデル中で OneToOneField を使うと、そのフィールドをモデルの主キーにしていました。 この仕様はもうなくなりましたが、主キーにしたければ手動で primary_key に 指定できます。この変更により、一つのモデル中で複数の OneToOneField を使 えるようになりました。

詳細な例は 一対一のリレーションを持つモデルの例 を参照してください。

カスタムのフィールド型

開発版の Django で新たに追加された機能です

既存のモデルフィールドが目的とするアプリケーションに合わない場合や、あまり 一般的でないデータベースカラムタイプを活用したい場合のために、独自のフィー ルドクラスを作成できます。独自のフィールドの作成方法の詳細は カスタムモデルフィールド のドキュメントで説明しています。

Meta オプション

モデルにメタデータを指定するには、以下のようにモデルの内部で class Meta を使います:

class Foo(models.Model):
    bar = models.CharField(max_length=30)

    class Meta:
        # ...

モデルのメタデータには、オブジェクトの並び規則など、「フィールドでないもの 全て」を入れます。

利用できる全ての Meta オプションのリストを以下に示します。どのオプショ ンも Meta の記述に必須ではありません。モデルに class Meta を追加す るかどうかもオプションです。

abstract

開発版の Django で新たに追加された機能です

True に設定すると、モデルを抽象ベースクラスにします。詳しくは 抽象ベースクラス の節を参照してください。デフォルト値は False です。

db_table

モデルの使うデータベーステーブルの名前です:

db_table = "music_album"

このオプションを指定しなければ、Django は app_label + '_' + model_class_name を使います。詳しくは後述の「テーブル 名」を参照してください。

データベーステーブル名が SQL の予約語であったり、 Python 変数名として使えな い文字を含んでいる場合 (よくあるのはハイフンです) でも問題はありません。 Django は背後でカラム名とテーブル名をクオートします。

get_latest_by

モデル中の DateField または DateTimeField の名前です。このオプショ ンは、モデルの Managerlatest() メソッドが使うデフォルトのフィー ルドを指定します。

例えば:

get_latest_by = "order_date"

完全な例は latest() のドキュメント を参照してください。

order_with_respect_to

オブジェクトを指定のフィールドで「並べ替え可能 (orderable)」にします。この オプションを使うのは、リレーションの張られたオブジェクトを、親オブジェクト に従って並べ替えたい場合がほとんどです。例えば、 AnswerQuestion にリレーションを張っており、一つの Question に複数の Answer があっ て、 Answer の順番が重要である場合は以下のようにします:

class Answer(models.Model):
    question = models.ForeignKey(Question)
    # ...

    class Meta:
        order_with_respect_to = 'question'

ordering

オブジェクトのリストを取得するときに使われる、オブジェクトのデフォルトの並 び順規則です:

ordering = ['-order_date']

値は文字列のタプルやリストです。各文字列はフィールドの名前で、降順に並べる 場合にはオプションの "-" を先頭に付けます。先頭に "-" のないフィールドは昇 順に並べられます。順番をランダムにするには "?" を使って下さい。

例えば、 pub_date フィールドで昇順に並べる場合には以下のようにします:

ordering = ['pub_date']

例えば、 pub_date フィールドで降順に並べる場合には以下のようにします:

ordering = ['-pub_date']

例えば、 pub_date フィールドで降順に並べ、さらに author で昇順に場 合には以下のようにします:

ordering = ['-pub_date', 'author']

その他の例は 並び順の指定例 を参照してください。

ordering にいくつフィールドがあっても、 admin サイトは最初のフィールド しか使わないので注意してください。

permissions

オブジェクトの生成時にパーミッションテーブルに追加するパーミッションのリス トです。 admin セットをもつオブジェクトには、追加、削除、変更のパーミッ ションが自動的に生成されます。以下の例では、 can_deliver_pizzas という追 加のパーミッションを定義しています:

permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)

(permission_code, human_readable_permission_name) の形式をとる 2 要素の タプルからなるリストです。

unique_together

組み合わせとして一意にしなければならないフィールドセットのリストです:

unique_together = (("driver", "restaurant"),)

この制約は Django の admin 上で使われるとともに、データベースレベルでも強制 されます (すなわち、適切な UNIQUE 文が CREATE TABLE 文に入ります)。

unique_together に指定するフィールドは、全て同じモデルのフィールドでな ければなりません。 モデルの継承 を行っている場合、親クラスのフィールドは unique_together に指定できません。

開発版の Django で新たに追加された機能です

便宜上、 unique_together は一つのリストのときは単一セットのフィールドとして 扱います:

unique_together = ("driver", "restaurant")

verbose_name

人間可読なオブジェクト名の単数形です:

verbose_name = "pizza"

この引数を指定しない場合、Django はクラス名を解体した文字列を使います。例え ば CamelCasecamel case になります。

verbose_name_plural

オブジェクトの複数形名です:

verbose_name_plural = "stories"

この引数を指定しない場合、Django は verbose_name + "s" を使います。

テーブル名

Django はモデルクラス名とモデルクラスの入っているアプリケーションの名前から データベーステーブル名を自動的に導出して、ユーザが時間を無駄使いしなくてす むようにしています。モデルのデータベーステーブル名は、モデルの「アプリケー ションラベル」、すなわち manage.py startapp に指定する名前と、モデルの クラス名をアンダースコアで結合したものになります。

例えば、 (manage.py startapp bookstore で作成した) bookstore とい うアプリケーションがあったとしましょう。 class Book として定義したモデ ルはデータベース中では bookstore_book というテーブルになります。

データベーステーブル名をオーバライドするには、 class Meta 中で db_table パラメタを指定してください。

自動的な主キーフィールド

デフォルトでは、 Django は各モデルに以下のフィールド:

id = models.AutoField(primary_key=True)

を追加します。これは自動的に値をインクリメントして追加してゆくフィールドで、 主キーに使われます。

カスタムの主キーを指定したければ、いずれかのフィールドに primary_key=True を指定してください。 primary_key が設定されている のを Django が見つけると、 id カラムを自動的に追加しません。

各モデルには必ず一つ primary_key=True のフィールドが必要です。

pk プロパティ

開発版の Django で新たに追加された機能です

主キーを自前で定義しているか、 Django によって供給されているかに 関係なく、それぞれのモデルは pk と呼ばれるプロパティを持ちます。 これは モデルの通常の属性のように振る舞いますが、実はモデルの主キーフィールド のエイリアスです。その他の属性と同じように、この値は読み書き可能で、モデルの フィールドを修正し更新できます。

Admin オプション

自作のモデルを admin サイト上で可視にするには、以下のようにモデルの内部で "class Admin" を使います:

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

    class Admin:
        # オプションをここに記述します
        pass

Admin クラスは admin サイト上でのモデルの表示方法を Django に教えます。

利用可能な Admin オプションのリストを示します。これらのクラス変数は全て オプションです。オプションを全く指定せずに admin インタフェースを使いたけれ ば、以下のように pass を使います:

class Admin:
    pass

class Admin をモデルに追加するかどうかも全くのオプションです。

date_hierarchy

date_hierarchy をモデルの DateFieldDateTimeField に指定する と、変更リストのページに、指定フィールドの日付を使って日付ベースで絞り込み できるナビゲーションが組み込まれます。

例:

date_hierarchy = 'pub_date'

fields

admin の「追加 (add)」および「変更 (change)」ページのレイアウトを制御するに は、 fields を使います。

fields は 2 要素のタプルのリストです。各タプルは admin フォームページ上 の <fieldset> を表します (<fieldset> はフォームの「セクション」にな ります)。

フィールドセットは (name, field_options) の形式をとります。 name はフィールドセットの名前を表す文字列で、 field_options はフィールドセッ トに表示すフィールドの情報を入れた辞書です。

django.contrib.flatpages.FlatPage モデルから抜き出した例を示します:

class Admin:
    fields = (
        (None, {
            'fields': ('url', 'title', 'content', 'sites')
        }),
        ('Advanced options', {
            'classes': 'collapse',
            'fields' : ('enable_comments', 'registration_required', 'template_name')
        }),
    )

このフィールドセットによって、 admin のページは以下のようになります:

http://media.djangoproject.com/img/doc/flatfiles_admin.png

fields を指定しない場合、 Django は AutoField でなくかつ editable=True であるフィールドの各々を、モデルに定義した順番に 個別のフィールドセットとして表示します。

field_options 辞書には以下のようなキーがあります:

fields

フィールドセット内に表示するフィールド名からなるタプルです。必須のキーです。

例:

{
'fields': ('first_name', 'last_name', 'address', 'city', 'state'),
}

同じ行に複数のフィールドを表示したい場合、それらのフィールドをタプルでラッ プして入れます。下の例では、 first_namelast_name が同じ行に 表示されます:

{
'fields': (('first_name', 'last_name'), 'address', 'city', 'state'),
}

classes

フィールドセットに適用される追加の CSS クラス名です。単純な文字列を指定しま す。

例:

{
'classes': 'wide',
}

また、以下の例のように、スペースで区切ると複数のクラスを適用できます:

{
'classes': 'wide extrapretty',
}

デフォルトのスタイルシートで定義されている便利なクラスとして collapsewide があります。 collapse スタイルのフィールドは、 admin ページ では最初折り畳まれ (collapse) ており、小さな "クリックして展開 (click to expand)" リンクに置き換わっています。 wide スタイルのフィールドセットに は水平方向に追加のスペースが加わります。

description

各フィールドセットの先頭に表示する追加の文字列で、オプションです。この文字 列はそのまま表示されるので、 HTML を使えますし、 HTML で特別扱いされる文字 (アンパーサンドなど) は自分でエスケープしておかねばなりません。

js

JavaScript ファイルの URL を表す文字列のリストです。 JavaScript は admin ス クリーンに <script src="" タグでリンクされます。このオプションは、特定 の admin ページを JavaScript で操作したり、特定のフィールドにデフォルト値を 埋めるための "quick link" を提供したりするために使えます。

http:/// で始まらない相対 URL を使うと、 Django の admin はリン クに settings.ADMIN_MEDIA_PREFIX をプレフィクスします。

list_display

admin の変更リストページに表示するフィールドを制御するには list_display を使います。

例:

list_display = ('first_name', 'last_name')

list_display を指定しなければ、 admin サイトは各オブジェクトの __str__() 表現を表示するカラムを一つだけ表示します。

list_display にはいくつか特殊なケースがあります:

  • フィールドが ForeignKey の場合、関連づけられているオブジェクトの __unicode__() を表示します。

  • ManyToManyField フィールドの表示は、テーブルの各行に対して個別に SQL 文を実行することになってしまうのでサポートしていません。どうして も表示させたいなら、カスタムメソッドをモデルに実装して、メソッドの名 前を list_display に追加してください (list_display へのカスタ ムメソッドの追加については、後で詳しく説明しています)。

  • フィールドが BooleanFieldNullBooleanField の場合、 TrueFalse の代りに "オン" や "オフ" を示すアイコンを表示 します。

  • フィールド名がモデルのメソッドになっていた場合、メソッドを呼び出 した結果を表示します。このメソッドには、フィールドのヘッダに使うた めの short_description という関数属性がなければなりません。

    例を示します:

    class Person(models.Model):
        name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        class Admin:
            list_display = ('name', 'decade_born_in')
    
        def decade_born_in(self):
            return self.birthday.strftime('%Y')[:3] + "0's"
        decade_born_in.short_description = 'Birth decade'
    
  • 渡された文字列がモデルのメソッド名の場合、 Django はデフォルトでメソッ ドの出力をエスケープします。メソッドの出力をエスケープしたくない場合 には、メソッドの allow_tags 属性の値を True にしてください。

    以下にモデル例を示します:

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        last_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        class Admin:
            list_display = ('first_name', 'last_name', 'colored_name')
    
        def colored_name(self):
            return '<span style="color: #%s;">%s %s</span>' % \
                (self.color_code, self.first_name, self.last_name)
        colored_name.allow_tags = True
    
  • 渡された文字列がモデルのあるメソッドを指しており、メソッドが True か False を返す場合、メソッドの boolean 属性を True に設定してお くと、Django は "on" や "off" のアイコンを表示します。

    以下に最終的なモデルの例を示します:

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        birthday = models.DateField()
    
        class Admin:
            list_display = ('name', 'born_in_fifties')
    
        def born_in_fifties(self):
            return self.birthday.strftime('%Y')[:3] == 5
        born_in_fifties.boolean = True
    
  • __str__() および __unicode__() メソッドは他のモデルメソッドと 同じように list_display に入れられるので、以下のように書いても全 く問題ありません:

    list_display = ('__unicode__', 'some_other_field')
    
  • list_display の要素のうち、モデルのフィールドでないものには、変更 リストページで並び順を変えるときのカラムには使えません。これは Django がオブジェクトの整列をデータベースレベルで行っており、カスタムメソッ ドがどうやってオブジェクトを整列するかを SQL レベルで知る術がないため です。

  • 通常、 list_display の要素のうち、モデルのフィールドでないものに は、変更リストページで並び順を変えるときのカラムには使えません。 (Django はソートをすべてデータベースレベルで行うからです)

    list_display の要素が実際にデータベース上のあるフィールドを指して いる場合、 admin_order_field という属性を使って、 Django にそのこ とを教えられます。例えば:

    class Person(models.Model):
        first_name = models.CharField(max_length=50)
        color_code = models.CharField(max_length=6)
    
        class Admin:
            list_display = ('first_name', 'colored_first_name')
    
        def colored_first_name(self):
            return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
        colored_first_name.allow_tags = True
        colored_first_name.admin_order_field = 'first_name'
    

    この例では、 Django は Admin 上で colored_first_name を並べ変える 際に first_name フィールドを使います。

list_filter

admin の変更リストページの右側のサイドバーにあるフィルタを有効にするには、 list_filter を設定します。この値はフィールド名のリストにします。 各フィールド名は BooleanField, CharField, DateField, DateTimeField, IntegerField, ForeignKey のいずれかでなければ なりません。

以下の例は django.contrib.auth.models.User モデルからとったもので、 list_displaylist_filter の仕組みを示しています:

class Admin:
    list_display = ('username', 'email', 'first_name', 'last_name',
                    'is_staff')
    list_filter = ('is_staff', 'is_superuser')

上のコードによって、 admin の変更リストは以下のようになります:

http://media.djangoproject.com/img/doc/users_changelist.png

(この例では、後述する search_fields も定義しています。)

list_per_page

admin 変更リストをページ分割 (paginate) で表示するときに、各ページに何個の アイテムを表示するかを決めます。デフォルト値は 100 です。

ordering

ordering を設定すると、 admin の更新リストにおける整列順を指定できます。 値はタプルからなるリストで、モデルの ordering パラメタと同じ形式で指定 します。

save_as

save_as を指定すると、オブジェクト編集ページで「別名で保存 (save as)」 機能を使えるようになります。

通常、オブジェクト編集ページには三つの保存オプション、すなわち「保存 (Save)」、「保存して編集を続ける (Save and continue editing)」、「保存して もう一つ追加 (Save and add another)」があります。 save_asTrue にすると。「保存してもう一つ追加」は「別名で保存 (Save as)」に置き換わりま す。

「別名で保存」は、現在のオブジェクトをそのまま保存するのではなく、(新たな ID を持った) 別のオブジェクトとして保存することです。

save_on_top

save_on_top を指定すると、 admin の変更フォームの最上部に保存ボタンを追 加できます。

通常、保存ボタンはフォームの最下部だけに表示されます。 save_on_top を指 定すると、ボタンは最下部だけでなく最上部にも表示されます。

デフォルトでは、 save_on_topFalse です。

search_fields

search_fields を指定すると、 admin の変更リストページで検索ボックスを使 えるようになります。この値はユーザが検索クエリをテキストボックスに入力した ときに検索の対象になるフィールド名のリストです。

フィー ルドは CharFieldTextField のような何らかのテキストフィー ルドでなければなりません。 DB 照合 API の「リレーション追跡」表記を使えば、 ForeignKey を介したフィールドの指定も行えます:

search_fields = ['foreign_key__related_fieldname']

admin の検索ボックスで検索を実行すると、 Django は検索クエリを単語に分解し て、各単語を含むような全てのオブジェクトを返します。検索は大小文字を区別せ ず、 search_fields に指定したフィールドのうち少なくとも一つに単語が入っ ていればヒットします。例えば、 search_fields['first_name', 'last_name'] に設定されている場合、ユーザが john lennon を検索すると、 Django は以下のような WHERE 節を持った SQL に等価な検索を実行します:

WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')

より高速な、あるいはより制約の厳しい検索を行うには、フィールド名の前に以下 のような演算子を置きます:

^

フィールドの先頭にマッチします。例えば、 search_fields['^first_name', '^last_name'] にして、ユーザが john lennon を検 索した場合、Django は以下のような WHERE 節の SQL に等価な検索を実行 します:

WHERE (first_name ILIKE 'john%' OR last_name ILIKE 'john%')
AND (first_name ILIKE 'lennon%' OR last_name ILIKE 'lennon%')

このクエリを使うと、データベースはカラムの先頭部分だけをチェックすれば よく、カラム中のデータ全体を調べなくてもよくなるため、通常の '%john%' クエリよりも効率的になります。加えて、カラムにインデクスが 設定されていれば、データベースによっては LIKE クエリであってもイン デクスを使ったクエリを実行できるという利点があります。

=

大小文字を区別しない厳密一致です。例えば、 search_fields['=first_name', '=last_name'] にして、ユーザが john lennon を検 索した場合、 Django は以下のような WHERE 節の SQL に等価な検索を実行 します:

WHERE (first_name ILIKE 'john' OR last_name ILIKE 'john')
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')

クエリ入力はスペース区切りなので、この例に従うと、 first_name'john winston' (スペースを含むもの) であるようなレコードは検索でき ないので注意してください。

@
全文検索マッチを実行します。デフォルトの search メソッドに似ていますが、 インデクスを使います。現在のところ MySQL でしか使えません。

マネジャ

マネジャ (Manager) とは、データベースクエリ操作を Django モデルに提供し ているインタフェースです。 Django アプリケーション内のモデルは全て少なくと も一つマネジャを備えています。

マネジャクラス Manager の動作はデータベース API ドキュメントの オブジェクトの取得 の節で説明していますが、この節ではマネジャの挙動をカ スタマイズするためのモデルオプションについて具体的に触れます。

マネジャ名

デフォルトでは、 Django は全ての Django モデルクラスに object という名 前で Manager オブジェクトを追加します。ただし、 objects をフィール ド名として使いたい場合や、マネジャに objects 以外の名前をつけたい場合に は、モデルごとに名前を変えてやる必要があります。クラス中でマネジャの名前を 変更するには、 models.Manager() 型のクラス属性を定義します。例えば:

from django.db import models

class Person(models.Model):
    #...
    people = models.Manager()

のようにすると、 Person.objectsAttributeError 例外になり、 Person.people.all()Person オブジェクトのリストを提供するように なります。

カスタムマネジャ

基底クラスの Manager クラスを拡張して、モデル中でカスタムのマネジャをイ ンスタンス化すれば、モデルでカスタムのマネジャを使えます。

マネジャをカスタマイズする理由は大きく分けて二つあります。一つはマネジャに 追加のメソッドを持たせたい場合、もう一つはマネジャの返す初期 QuerySet を変更したい場合です。

追加のマネジャメソッド定義

モデルに「テーブルレベル」の機能を持たせたい場合、マネジャへのメソッドは良 い方法です。 (「行レベル」の機能を持たせたい、例えばモデルオブジェクトの個々 のインスタンスに影響する関数を実装したい場合には、カスタムのマネジャメソッ ドではなく モデルのメソッド を使って下さい。)

カスタムのマネジャメソッドは何を返してもかまいません。 QuerySet を返さ なくてもよいのです。

例えば、以下のカスタムマネジャでは、 with_counts() というメソッドを提供 しています。このメソッドは全ての OpinionPoll オブジェクトからなるリスト を返しますが、その際に集約クエリの結果である num_responses という追加の 属性を追加します:

class PollManager(models.Manager):
    def with_counts(self):
        from django.db import connection
        cursor = connection.cursor()
        cursor.execute("""
            SELECT p.id, p.question, p.poll_date, COUNT(*)
            FROM polls_opinionpoll p, polls_response r
            WHERE p.id = r.poll_id
            GROUP BY 1, 2, 3
            ORDER BY 3 DESC""")
        result_list = []
        for row in cursor.fetchall():
            p = self.model(id=row[0], question=row[1], poll_date=row[2])
            p.num_responses = row[3]
            result_list.append(p)
        return result_list

class OpinionPoll(models.Model):
    question = models.CharField(max_length=200)
    poll_date = models.DateField()
    objects = PollManager()

class Response(models.Model):
    poll = models.ForeignKey(Poll)
    person_name = models.CharField(max_length=50)
    response = models.TextField()

この例では、 OpinionPoll.objects.with_counts() を使うと、 num_responses 属性を備えた OpinionPoll オブジェクトのリストを返しま す。

この例でもう一つ注意して欲しいのは、マネジャメソッドが自分の属しているモデ ルクラスを取り出すために self.model にアクセスできるという点です。

初期 QuerySet の変更

マネジャのベースの QuerySet は、システム上の全てのオブジェクトを返しま す。例えば、以下のモデル:

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

では、 Book.objects.all() とすると、データベース上の全ての books を返し ます。

Manager.get_query_set() メソッドをオーバライドすれば、 Manager のベー スの QuerySet をオーバライドできます。 get_query_set() は必要なプロ パティを備えた QuerySet を返さねばなりません。

例えば、以下のモデルには 二つの マネジャがあります。片方は全てのオブジェ クトを返し、もう一方は Roald Dahl の書いた本だけを返します:

# まず Manager のサブクラスを定義します。
class DahlBookManager(models.Manager):
    def get_query_set(self):
        return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')

# 次に Book モデルに明示的にフックします。
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)

    objects = models.Manager() # デフォルトマネジャ。
    dahl_objects = DahlBookManager() # Dahl 縛りのマネジャ。

このモデル例では、 Book.objects.all() はデータベース上の Book を全て返 しますが、 Book.dahl_objects.all() は Roald Dahl の書いた本だけを返しま す。

get_query_set()QuerySet オブジェクトを返すので、もちろん filter()exclude() をはじめ全ての QuerySet メソッドを使えま す。従って、以下のような文を実行できます:

Book.dahl_objects.all()
Book.dahl_objects.filter(title='Matilda')
Book.dahl_objects.count()

この例はもう一つ興味深いテクニックの存在を示しています。それは同じモデルで 複数のマネジャを使えるということです。モデルには、好きなだけマネジャのイン スタンスをアタッチできます。この手法を使うと、よく利用するフィルタをモデル に簡単に実装できます。

例えば:

class MaleManager(models.Manager):
    def get_query_set(self):
        return super(MaleManager, self).get_query_set().filter(sex='M')

class FemaleManager(models.Manager):
    def get_query_set(self):
        return super(FemaleManager, self).get_query_set().filter(sex='F')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
    people = models.Manager()
    men = MaleManager()
    women = FemaleManager()

この例では、 Person.men.all(), Person.women.all(), Person.people.all() といったクエリを発行できるようになっており、期待通 りの結果を得られます。

カスタムのマネジャオブジェクトを使う場合、 Django がモデル内に最初に見つけ たマネジャ (モデルに定義した順番で最初のマネジャ) は特別扱いされるというこ とに注意してください。 Django はクラス内で最初に見つけたマネジャを「デフォ ルトの」マネジャにし、このデフォルトマネジャを (admin アプリケーション以外 でも) あちこちでモデルのマネジャとして使います。ですから、 get_query_set() のオーバライドによって、扱いたいオブジェクトを取り出せ なくなるような羽目に陥らないように、デフォルトマネジャの選択には細心の注意 を払ってください。

モデルのメソッド

カスタムの行レベル ("row-level") の機能をオブジェクトに実装するには、カスタ ムのメソッドを定義します。 Manager メソッドの目的が「テーブル級 (table-wide)」 の操作であるのに対し、モデルメソッドは個々のモデルインスタン スに対して作用します。

このモデルメソッドは、ビジネスロジックをモデルというただ一箇所にまとめてお くのに有用なテクニックになります。

例えば、以下のモデル例にはいくつかカスタムメソッドがあります:

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    birth_date = models.DateField()
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=50)
    state = models.USStateField() # Yes, this is America-centric...

    def baby_boomer_status(self):
        "Returns the person's baby-boomer status."
        import datetime
        if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
            return "Baby boomer"
        if self.birth_date < datetime.date(1945, 8, 1):
            return "Pre-boomer"
        return "Post-boomer"

    def is_midwestern(self):
        "Returns True if this person is from the Midwest."
        return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')

    def _get_full_name(self):
        "Returns the person's full name."
        return '%s %s' % (self.first_name, self.last_name)
    full_name = property(_get_full_name)

この例の最後のメソッドは プロパティ (property) です。詳しくは プロパティの説明 を参照してください。

いくつかのメソッドには特別な意味があります:

__str__

__str__() は、オブジェクトに対して str() を呼び出した際に返す内容を 定義するための Python の特殊メソッドです。 Django はそこかしこで str(obj) (または unicode(obj) -- 下記参照) を使っています。ほとんど は、 Django の admin サイトでオブジェクトをレンダリングして表示したときの値 として、またオブジェクトを表示するときにテンプレートに挿入される値として使 われています。従って、オブジェクトの __str__ は、人間可読なわかりやすい 文字列を返さねばなりません。必須ではありませんが、強く推奨します (ただし、 そこかしこに __str__ メソッドを突っ込んでしまう前に __unicode__ の 説明を良く読んでくださいね)。

例えば:

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

    def __str__(self):
        # first_name および last_name は Unicode 文字列なので、
        # django.utils.encoding.smart_str() を使っています。
        return smart_str('%s %s' % (self.first_name, self.last_name))

__unicode__

__unicode__() メソッドは、オブジェクトに対して unicode() を呼び出し た際に呼び出されます。Django のデータベースバックエンドはモデルの属性値とし て Unicode 文字列を返すので、通常はモデルの __unicode__() メソッドを定 義するとよいでしょう。前節の例を __unicode__() を使って書き直すと、以下 のように簡単になります:

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

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)

モデルに __unicode__() メソッドだけを定義して、 __str__() は定義し ないでおくと、 Django が自動的に __str__() メソッドをモデルに追加します。 この __str__() メソッドは、 __unicode__() を呼び出して、その戻り値 を UTF-8 でエンコードした文字列を返します。開発上はこの仕様に従い、 __unicode__() だけを定義して、文字列オブジェクトへの変換は Django 任せ にするよう勧めます。

get_absolute_url

オブジェクトの URL の計算方法を Django に教えるには get_absolute_url メ ソッドを定義してください。例えば:

def get_absolute_url(self):
    return "/people/%i/" % self.id

Django はこのメソッドを admin インタフェースで使います。オブジェクトが get_absolute_url() を定義していた場合、オブジェクトの詳細ページには「サ イト上で表示 (View on site)」というリンクが表示されます。このリンクは、オブ ジェクトの get_absolute_url() に基づいて、オブジェクトを公開しているビュー に直接飛べるようになっています。

また、その他にも、例えば 配信フィードフレームワーク などで、 get_absolute_url() を使うことでユーザの利便性を高めています。

テンプレートでオブジェクトの URL を表示する場合、ハードコードするのでは なく get_absolute_url() を使うようにするとよいでしょう。例えば、以下の テンプレート:

<a href="/people/{{ object.id }}/">{{ object.name }}</a>

は良い例ではなく、以下のようにするとよいでしょう:

<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>

Note

get_absolute_url() の返す文字列は ASCII 文字だけで構成しなければな りません (RFC 2396 の URI 仕様でそのように要求されています)。また、 必要に応じて URL エンコードせねばなりません。 get_absolute_url() を 使うコードやテンプレートが、 get_absolute_url() の返す文字列を、追 加の処理を施さなくても直接利用できるようにせねばならないのです。 URI に Unicode 文字列を沢山使っているのなら、 django.utils.encoding.iri_to_uri も使うことになるでしょう。

カスタム SQL の実行

自作のモデルメソッドやモジュールレベルのメソッドでは、自由にカスタムの SQL 文を書けます。 django.db.connection というオブジェクトが現在のデータベー ス接続を表現しています。カスタムSQL を使うには、まず connection.cursor() を呼び出してカーソルオブジェクトを取得し、次いで cursor.execute(sql, [params]) を呼び出して SQL を実行した後、 cursor.fetchone()cursor.fetchall() を読んで結果行を返します。例 えば:

def my_custom_sql(self):
    from django.db import connection
    cursor = connection.cursor()
    cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
    row = cursor.fetchone()
    return row

connectioncursor は標準の Python DB-API が提供する機能の (トランザクションの扱い を除いた) ほとんどを実装しています。 Python DB-API に詳しくないのなら、上の SQL 文の cursor.execute() でパラ メタを直接 SQL に入れるのではなく、プレースホルダ "%s" を使っていること に注意して下さい。このテクニックを使うと、根底にあるデータベースライブラリ は必要に応じて自動的にパラメタをクオートしたりエスケープ処理したりします。 (また、Django はプレースホルダ文字として SQLite の Python バインディングが 使っている "?" ではなく "%s" を使うので注意してください。これは インタフェースに一貫性をもたせるための設計です。)

注意: WHERE 節を自分で設定したいだけなら、標準の照合 API に wheretablesparams といった引数を指定して実現できます。 extra() のドキュメント を参照してください。

デフォルトモデルメソッドのオーバライド

データベース API のドキュメント でも説明したように、 Django は各モデルに 自動的にいくつかメソッドを追加します。 save()delete() がその例 です。これらのメソッドをオーバライドすれば、その挙動を変更できます。

組み込みメソッドをオーバライドする古典的なユースケースは、オブジェクトを保 存する際に何か別の処理を行うというものです。例えば:

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

    def save(self):
        do_something()
        super(Blog, self).save() # 「実際の」 save() を呼び出します。
        do_something_else()

また、以下のようにすれば保存を抑止できます:

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

    def save(self):
        if self.name == "Yoko Ono's blog":
            return # Yoko は自分のブログを持っていません!
        else:
            super(Blog, self).save() # 「実際の」save() を呼び出します。

モデルの継承

開発版の Django で新たに追加された機能です

Django のモデルクラス継承は、 Python の通常のクラス継承とほぼ同じように動作 します。モデル継承を実現するには、一つだけきめておかねばならないことがあり ます。それは、親クラスに独自のデータベーステーブルを持たせるか、親クラスを 単なるホルダとして使い、子クラスで共通の情報を持たせるだけにするかです。

複数の子モデルクラスでいちいち同じ情報を入力せずに済ませるために、親モデル クラスに共通の情報を持たせたいことはよくあります。親モデルクラスを単体で使 うことがないのなら、 抽象ベースクラス を使うのがよいでしょう。一方、(他 のアプリケーションなどにある) 既存のモデルをサブクラス化して拡張したり、個々 のモデルに固有のデータベースを持たせたいような場合には、 マルチテーブル継承 を使うのがよいでしょう。

抽象ベースクラス

抽象ベースクラスは、たくさんのモデルで共通の情報を入れておきたいときに便利 な仕組みです。抽象ベースクラスを定義するには、ベースクラス定義の、 Metaabstract=True を入れておきます。モデルを抽象ベースクラスとして定義す ると、そのクラスはデータベーステーブルを生成しません。その代り、他のモデル を定義するときに抽象ベースクラスを親にすると、ベースクラスのフィールドが子 クラスに追加されます。抽象ベースクラスで定義したフィールドと同じ名前のフィー ルドを子クラスで定義しようとするとエラーを引き起こします (Django は例外を送 出します)。

例を示しましょう:

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 の三つのフィールドを持つようになります。. CommonInfo モ デルは抽象ベースクラスなので、通常の Django モデルとしては使えません。 CommonInfo はデータベーステーブルを作らず、マネジャなども持ちません。

ほとんどの用途で使えるのは、このタイプのモデル継承でしょう。抽象ベースクラ スは、子クラスで共通の情報を Python レベルに切り出しながらも、データベース レベルでは、各子クラに一つのデータベーステーブルを生成します。

Meta の継承

抽象ベースクラスを作成するとき、 Django は抽象ベースクラスの内部クラス Meta をクラス属性として参照できるようにします。子クラスで Meta クラスを定義しない場合、親クラスの Meta がそのまま継承されます。 子クラスで Meta を拡張したければ、親クラスをサブクラス化できます。 以下に例を示しましょう:

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

class Student(CommonInfo):
    ...
    class Meta(CommonInfo.Meta):
        db_table = 'student_info'

Django は抽象ベースクラスの Meta クラスを生成するときに一つだけ手を加え ます。すなわち、 Meta の属性を組み込む前に、 abstract=False を設定 するのです。これにより、抽象ベースクラスの子クラスが自動的に非抽象ベースク ラスになります。もちろん、他の抽象ベースクラスを継承した新たな抽象ベースク ラスも定義できます。継承するには、明示的に abstract=True をセットしてく ださい。

Meta クラスの属性の中には、抽象ベースクラスで定義しても意味のないものも あります。例えば、 db_table を抽象ベースクラスの Meta で定義すると、 その子クラス全て (で、独自に Meta を定義しないもの) が、同じデータベー ステーブルを使おうとしてしまいます。

マルチテーブル継承

Django では、継承の各階層にいるクラスが抽象クラスでない実際のモデルであるよ うな、もう一つのタイプのモデル継承をサポートしています。各モデルはそれぞれ が一個のデータベーステーブルを表現していて、個別にクエリを発行したり、イン スタンスを生成したりできます。継承の関係によって、親クラスと子クラスの間に は (自動生成された OneToOneField によって) リンクが張られます。以下の例 で説明しましょう:

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

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

Place の全てのフィールドは、 Restaurant からも使えます。しかし、そ れぞれのフィールドのデータは別々のテーブルに格納されます。従って、以下のよ うな操作をどちらも実行できます:

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

例えば、 Place であり、かつ Restaurant でもあるようなオブジェクトが あれば、モデル名を小文字にした属性を使って、 Place から Restaurant を取り出せます:

>>> p = Place.objects.filter(name="Bob's Cafe")
# Bob's Cafe が Restaurant オブジェクトなら、子クラスを返す:
>>> p.restaurant
<Restaurant: ...>

ただし、上の pRestaurant クラスで ない のなら (Place から 直接生成されたオブジェクトや、他のクラスの親クラスなら) p.restaurant はエラーを引き起こします。

Meta とマルチテーブル継承

マルチテーブル継承では、子クラスが親クラスの Meta クラスを継承する意味 がありません。 Meta オプションは全て親クラスだけに適用されるべきもので、 他のクラスに同じ内容を適用しても、矛盾した振る舞いを引き起こすだけです (これは、独自のテーブルを持たない抽象ベースクラスと対照的な部分です)。

従って、マルチテーブル継承の子クラスは親クラスの Meta クラスにアクセス する方法を持ちません。ただし、限られたケースで、子クラスが親クラスの挙動を 継承する場合があります。それは、子クラスで ordering または get_latest_by 属性を指定していない場合に、親クラスの属性を継承するとい うものです。

親クラスで整列カラムが指定されていて、子クラス側で整列カラムを指定したくな い場合は、明示的に空の整列カラムを指定してください:

class ChildModel(ParentModel):
    ...
    class Meta:
        # 親クラスの整列カラム設定の効果を除去する
        ordering = []

継承と逆リレーション

マルチテーブル継承は親クラスと子クラスを暗黙の OneToOneField でリンクす るので、前述の例のように、親クラスから子クラスをたどれます。しかし、子クラ スをたどるときに使う名前は、 ForeignKeyManyToManyField リレーショ ンを定義したときのデフォルトの related_name と同じ値を使っています。 従って、子クラスで ForeignKeyManyToManyField を別のクラスに向け て張るときには、 必ず related_name をフィールドに指定せねばなりませ ん。指定し忘れると、 Django は manage.py validatesyncdb 時にエ ラーを送出します。

例えば、上の Place クラスに対して、 ManyToManyField を持った別のサ ブクラスを定義してみましょう:

class Supplier(Place):
    # 全てのリレーションで related_name を定義すること
    customers = models.ManyToManyField(Restaurant,
            related_name='provider')

逆リレーションの詳細は、 データベース API リファレンス を参照してくださ い。とりあえずは、マルチテーブル継承で新たなモデルを作成したときには、 manage.py validate を実行して、エラーメッセージが出ないか確かめるように しましょう。

親クラスのリンクフィールドを定義する

すでに触れたように、 Django は子クラスと抽象クラスでない親クラスにリンクし た OneToOneField を自動的に生成します。親クラスへのリンク名を操作したけ れば、自分で OneToOneField を作成し、パラメタに parent_link=True を 渡してください。例えば、上の例で Supplier から Place への明示的なリ ンクフィールドを作成するには、以下のようにします:

class Supplier(Place):
    parent = models.OneToOneField(Place, parent_link=True)
    ...

多重継承

Python のサブクラスと同様、 Django のモデルも複数の親モデルクラスを継承でき ます。クラス内の名前解決には、 Python の通常の名前解決規則が適用されるので 注意してください。子クラスで特定の名前 (例えば Meta) を参照する場合、そ の名前を定義している最初のベースクラスの定義を使い、最初に名前が見つかった 時点で、それ以降同じ名前のオブジェクトの解決は行われません。従って、複数の 親クラスで別々に Meta クラスを定義していても、最初のベースクラスの Meta だけが使われ、それ以外は全て無視されます。

通常は、モデルの多重継承は必要ないでしょう。多重継承が便利なのは、主に特定 のフィールドやメソッドを追加するための ''mix-in'' クラスを使う場合です。 継承の階層構造はできるだけ単純に、分かりやすくしておきましょう。さもないと、 子クラスで扱っている情報が、どの親クラスから来たか調べるために四苦八苦する はめになるでしょう。

ファイル間にまたがるモデル

あるモジュールから別のモジュールへのリレーションは全く問題なく張れます。 リレーションを張るには、モデル定義の先頭でリレーション対称のモデルを import しておき、必要なところでそのモデルクラスを参照します。例えば:

from mysite.geography.models import ZipCode

class Restaurant(models.Model):
    # ...
    zip_code = models.ForeignKey(ZipCode)

モデルを使う

モデルを定義したら、最後のステップとして、そのモデルを 使う と Django に 教えます。

設定ファイルを編集して、 models.py の入ったモジュールの名前を INSTALLED_APPS 設定に追加してください。

例えば、アプリケーションのモデルが mysite.myapp.models モジュール ( manage.py startapp スクリプトで作成した、アプリケーションのパッケージ構 造) に収められている場合、 INSTALLED_APPS は以下のようになります:

INSTALLED_APPS = (
    #...
    'mysite.myapp',
    #...
)

SQL 初期化データの提供

Django では、 CREATE TABLE 文を実行した直後に任意の SQL をデータベースに渡 せるフックを提供しています。例えば、このフックを使えば、自動的にデフォルト のレコードをテーブルに追加したり SQL 関数を作成したりできます。

フックのからくりは単純です: Django は <appname> をアプリケーションディ レクトリの名前、 <modelname> をモデル名を小文字にした文字列として、 <appname>/sql/<modelname>.sql を探すようになっているだけです。

このドキュメントの冒頭にある Person の例で、モデルが myapp の下に置 かれていたとすると、 myapp/sql/person.sql というファイルに任意の SQL 文を指定できます。例えば以下のような命令を入れられます:

INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');

各 SQL ファイルには有効な SQL 文を入れておかねばなりません。 SQL ファイルは モデルのテーブルを生成する SQL が実行された直後にデータベースに直接パイプ入 力されます。

SQL ファイルは manage.pysqlcustom, sqlreset, sqlall および reset コマンドの実行時に参照されます。詳しくは manage.py のドキュメント を参照してください。

複数の SQL データファイルがある場合、個々のファイルを実行する順番は保証され ていないので注意して下さい。仮定していてよいのは、カスタムの SQL データファ イルを実行する前に、必ずデータベーステーブルは作成されているということだけ です。

データベースバックエンド特有の SQL データ

バックエンド特有の SQL データに対するフックもあります。例えば、 PostgreSQL と MySQL 向けに別々の初期データを用意するのなら、各アプリケーションごとに Django は <appname>/sql/<modelname>.<backend>.sql というファイルを探し ます。 <appname> はアプリケーションディレクトリの名前、 <modelname> はモデル名を小文字にした文字列、 <backend> は設定ファイルの DATABASE_ENGINE に指定するバックエンドの名前 (postgresql, mysql など) です。

バックエンド固有の SQL データは、バックエンド非固有の SQL データよりも前に 実行されます。例えば、アプリケーション中に sql/person.sql および sql/person.postgresql.sql が入っていて、 PostgreSQL をバックエンドにし てインストールを行った場合、 Django はまず sql/person.postgresql.sql の 内容を実行してから sql/person.sql を実行します。