モデル API リファレンス

revision-up-to:7239 (0.97pre SVN)

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

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

  • 各モデルは Python のクラスで、 django.db.models.Model のサブクラ スになります。
  • モデルの各属性値は、データベース上のあるフィールドを表現します。
  • モデルのメタデータ (フィールドで表現されない情報) は Meta と呼ば れる内部クラスに配置します。
  • Django の admin サイトで使われるメタデータは Admin と呼ばれる内部 クラスに配置します。
  • これらの情報をもとに、 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 になります。

追加のオプションとして、 prepopulate_from をとります。このオプションは、 admin フォームで JavaScript を介してスラグを自動生成する際に、元にするフィー ルドの名前からなるリストです:

models.SlugField(prepopulate_from=("pre_name", "name"))

DateTimeField, ForeignKey, ManyToManyField は prepopulate_from に入れら れません。

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

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)

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 であるということは、 blank=Falsenull=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 False でなければ、リレーション先のオブジェ クトをリレーション元のオブジェクトのページで 「インラインで」編集できます。これにより、リレー ション先のオブジェクトは独自の 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 リレーション先のオブジェクトから逆参照するとき に使われる名前です。詳しくは オブジェクトのリレーションに関する解説 を参照してください。
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' を使えば自分自身 へのリレーションを定義できます。また、モデル名の入った文字列を使えば、未定 義のモデルも参照できます。

実際には、 OneToOneFieldid フィールドを置き換えます (一対一のリレーションでは、主キーを共有するからです)。また、 admin インタ フェース上でオブジェクトを編集する際には、読み出し専用のフィールドとして 表示されます。

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

カスタムのフィールド型

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

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

Meta オプション

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

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

    class Meta:
        # ...

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

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

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 文に入ります)。

開発版の 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_display_links

list_display_links を設定すると、 list_display のどのフィールドを オブジェクトの「変更」ページにリンクするかを制御できます。

デフォルトでは、変更リストページはオブジェクトの変更ページ中の第一カラム、 すなわち list_display の先頭に指定したフィールドにリンクを張ります。 list_display_links を使うと、リンク先のカラムを変更できます。 list_display_links には、フィールド名のリストまたはタプルを (list_display と同じ形式で) 指定します。

list_display_links に指定するフィールド名は、一つでも複数でも構いません。 フィールド名が list_display に列挙されている限り、 Django はどんなに多 くの (あるいはどんなにわずかな) フィールドがリンクされていても問題にしませ ん。必要なのは、 list_display_links を使うには list_display を定義 しておかねばならない、ということだけです。

以下の例では、 first_name および last_name フィールドが変更変更リス トページにリンクされます:

class Admin:
    list_display = ('first_name', 'last_name', 'birthday')
    list_display_links = ('first_name', 'last_name')

最後に、 list_display_links を使うには list_display も指定せねばな らないので注意しましょう。

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 です。

list_select_related

list_select_related を設定すると、 admin の変更リストページに表示するオ ブジェクトリストを取得する際に select_related() を使うよう Django に指 示できます。これにより、データベースクエリの発行数を抑えられます。

値は True または False にします。デフォルトは False です。

list_display のいずれかのフィールドが ForeignKey の場合、 Django は この設定に関わらず select_related を使います。

select_related() の詳細は select_related() のドキュメント を参照 してください。

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()

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