モデルインスタンスリファレンス

revision-up-to:17812 (1.4) unfinished

このドキュメントでは、モデル API の詳細を解説します。このドキュメントは、 モデルデータベースクエリ といったガイドを前提にしているので、このドキュメントを 読む前に、予め読んで理解しておくとよいでしょう。

このリファレンスでは、 データベースクエリガイドWeblog のモデル例 を使います。

オブジェクトの生成

モデルの新たなインスタンスは、通常の Python のクラスと同じ方法で生成します:

class Model(**kwargs)

キーワード引数に指定できる名前は、モデルで定義したフィールドの名前です。 モデルのインスタンスを生成しても、 save() を呼び出すまで データベースは操作されません。

Validating objects

Django 1.2 で新たに登場しました: リリースノートを参照してください

There are three steps involved in validating a model:

  1. Validate the model fields
  2. Validate the model as a whole
  3. Validate the field uniqueness

All three steps are performed when you call a model’s full_clean() method.

When you use a ModelForm, the call to is_valid() will perform these validation steps for all the fields that are included on the form. See the ModelForm documentation for more information. You should only need to call a model’s full_clean() method if you plan to handle validation errors yourself, or if you have excluded fields from the ModelForm that require validation.

Model.full_clean(exclude=None)

This method calls Model.clean_fields(), Model.clean(), and Model.validate_unique(), in that order and raises a ValidationError that has a message_dict attribute containing errors from all three stages.

The optional exclude argument can be used to provide a list of field names that can be excluded from validation and cleaning. ModelForm uses this argument to exclude fields that aren’t present on your form from being validated since any errors raised could not be corrected by the user.

Note that full_clean() will not be called automatically when you call your model’s save() method, nor as a result of ModelForm validation. You’ll need to call it manually when you want to run one-step model validation for your own manually created models.

Example:

try:
    article.full_clean()
except ValidationError, e:
    # Do something based on the errors contained in e.message_dict.
    # Display them to a user, or handle them programatically.

The first step full_clean() performs is to clean each individual field.

Model.clean_fields(exclude=None)

This method will validate all fields on your model. The optional exclude argument lets you provide a list of field names to exclude from validation. It will raise a ValidationError if any fields fail validation.

The second step full_clean() performs is to call Model.clean(). This method should be overridden to perform custom validation on your model.

Model.clean()

This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field:

def clean(self):
    from django.core.exceptions import ValidationError
    # Don't allow draft entries to have a pub_date.
    if self.status == 'draft' and self.pub_date is not None:
        raise ValidationError('Draft entries may not have a publication date.')
    # Set the pub_date for published items if it hasn't been set already.
    if self.status == 'published' and self.pub_date is None:
        self.pub_date = datetime.datetime.now()

Any ValidationError exceptions raised by Model.clean() will be stored in a special key error dictionary key, NON_FIELD_ERRORS, that is used for errors that are tied to the entire model instead of to a specific field:

from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
    article.full_clean()
except ValidationError, e:
    non_field_errors = e.message_dict[NON_FIELD_ERRORS]

Finally, full_clean() will check any unique constraints on your model.

Model.validate_unique(exclude=None)

This method is similar to clean_fields(), but validates all uniqueness constraints on your model instead of individual field values. The optional exclude argument allows you to provide a list of field names to exclude from validation. It will raise a ValidationError if any fields fail validation.

Note that if you provide an exclude argument to validate_unique(), any unique_together constraint involving one of the fields you provided will not be checked.

オブジェクトの保存

オブジェクトをデータベースに書き戻すには、 save() を使います:

Model.save([force_insert=False, force_update=False, using=DEFAULT_DB_ALIAS])
Django 1.2 で新たに登場しました: The using argument was added.

If you want customized saving behavior, you can override this save() method. See 既存のモデルメソッドをオーバライドする for more details.

モデルの保存処理にはいくつか細かい注意点があります。以下の章を参照してください。

主キーの自動インクリメント

モデルに AutoField 、すなわち自動インクリメントされる 主キーがある場合には、オブジェクトに対して最初に save() を呼び出したときに 自動インクリメント値が計算され、保存されます:

>>> b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b2.id     # b には ID がないので None を返します。
>>> b2.save()
>>> b2.id     # 新たに保存されたオブジェクトの ID を返します。

ID の値は Django ではなくデータベースによって計算されるので、 save() を 呼び出すまでは ID の値は分かりません。

利便性のため、明示的に primary_key=True を指定したフィールドを 作成しないかぎり、デフォルトでは各モデルに id という名前の AutoField が追加されます。詳しくは AutoField のドキュメントを参照してください。

pk プロパティ

Model.pk

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

自動主キーの値を明示的に指定する

モデルが AutoField を持っていて、新たなオブジェクトの ID を保存時に明示的に指定したい場合、 ID を自動的に決定させずに保存前に明示的に 指定してください:

>>> b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.')
>>> b3.id     # Returns 3.
>>> b3.save()
>>> b3.id     # Returns 3.

自動主キーの値を手動で割り当てる場合、決して既に存在する主キーの値を割り当 てないようにしてください! 明示的な主キー値を持った新たなオブジェクトを作成 し、その主キーがすでにデータベース上に存在する場合、 Django は保存操作を新 たなオブジェクトの作成ではなく、既存のオブジェクトの変更とみなします。

上の 'Cheddar Talk' ブログを例にとると、以下の例はデータベース上の既存 のレコードをオーバライドしてしまいます:

b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
b4.save()  # Overrides the previous blog with ID=3!

この理由については後述の UPDATE と INSERT の区別 を参照してください。

主キーの衝突がないとはっきり判っている場合なら、自動主キーの値の明示的な指 定は大量のオブジェクトを保存する際にきわめて便利です。

オブジェクトの保存時に何が起きるのか

Django は以下の段階を踏んでオブジェクトを保存します:

  1. pre_save シグナルの発行 django.db.models.signals.pre_save シグナル の発行によって、何らかのオブジェクトを保存しようとしていることを通知 します。このシグナルを待ち受けている関数でカスタムの処理を実行できます。

  2. データの前処理 オブジェクトの各フィールドについて、保存時に自動的に 実行する必要があるデータ修飾処理がないか調べ、あれば実行します。

    ほとんどのフィールドは前処理を 伴いません 。フィールドのデータはそのまま 保存されます。前処理が行われるのは、特殊な挙動を示すフィールドだけです。 例えば、 auto_now=True に設定された DateField の場合、前処理の段階で、フィールドの内容が現在の日付になるようデータを 置き換えます (現時点では、「特殊な」挙動を示すフィールドのリストを 全て列挙したドキュメントはありません)。

  3. データベース保存用のデータ準備処理 各フィールドについて、フィールドの 現在の値を元にデータベースに保存できる型のデータを生成します。

    ほとんどのフィールドはデータ準備処理を 伴いません 。整数や文字列は Python オブジェクトとして「いつでもデータベースへの書き込みに使える」 形式になっています。ただ、より複雑なデータ型の場合、なにがしかの修飾 が必要なことがあります。

    例えば、 DateField は、データの保存に Python の datetime 型を使います。データベースは datetime オブジェクトを 保存しないので、データベースに保存するには、フィールドの値を ISO 準拠の日付文字列に変換せねばなりません。

  4. データベースへの保存 前処理と準備処理を経たデータが SQL 文に組み込まれ、 データベースに挿入されます。

  5. post_save シグナルの発行 django.db.models.signals.pre_save シグナルと同じく、オブジェクトが 成功理に保存されたことを通知するために django.db.models.signals.post_save シグナルが発行されます。

UPDATE と INSERT の区別

Django データベースオブジェクトがオブジェクトの作成と変更に同じ save() メソッドを使っていることにお気づきかもしれませんね。 Django は INSERTUPDATE SQL 文のどちらを使うべきかの判断を抽象化しています。具体的 に言うと、 save() を呼び出したときに、Django は以下のアルゴリズムに従い ます:

  • オブジェクトの主キー属性の評価値が False でない場合 (None や 空文字列の場合などでない場合) 、 Django は SELECT クエリを使って、 該当する主キーを持つレコードが存在するかどうか調べます。
  • 該当する主キーを持つレコードがデータベース上に存在する場合には UPDATE クエリを使います。
  • オブジェクトの主キー属性が設定 されていない 場合や、主キーが設定さ れているが該当するレコードは存在しない場合、 INSERT を使います。

新たなオブジェクトを保存する際、まだ使われていない値を主キーに指定できる保 証がないかぎり、主キーの値を明示的に指定しないよう注意してください。詳しく は上記の 自動主キーの値を明示的に指定する の節や、後述の INSERT や UPDATE を強制する を参照してください。

INSERT や UPDATE を強制する

ごく稀に、 save() メソッドに INSERT だけを実行させ、 UPDATE にフォールバックさせたくない、あるいはその逆、すなわち UPDATE が可能なら実行するが、新たなレコードの INSERT はさせたくないような場合が あります。そんなときには、 force_insert=Trueforce_update=True パラメタを save() メソッドに渡してください。 明らかなことではありますが、INSERTUPDATE は同時に行えないので、 両方のパラメタを同時に渡すとエラーを引き起こします。

このパラメタが必要なケースは本当にごく稀な場合だけです。たいていは、 Django は正しい SQL で保存を行いますし、パラメタをオーバライドすると、追跡の困難な エラーにつながる恐れがあります。特殊な用途でだけ、このパラメタを使ってくだ さい。

Updating attributes based on existing fields

Sometimes you’ll need to perform a simple arithmetic task on a field, such as incrementing or decrementing the current value. The obvious way to achieve this is to do something like:

>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold += 1
>>> product.save()

If the old number_sold value retrieved from the database was 10, then the value of 11 will be written back to the database.

This sequence has a standard update problem in that it contains a race condition. If another thread of execution has already saved an updated value after the current thread retrieved the old value, the current thread will only save the old value plus one, rather than the new (current) value plus one.

The process can be made robust and slightly faster by expressing the update relative to the original field value, rather than as an explicit assignment of a new value. Django provides F() expressions for performing this kind of relative update. Using F() expressions, the previous example is expressed as:

>>> from django.db.models import F
>>> product = Product.objects.get(name='Venezuelan Beaver Cheese')
>>> product.number_sold = F('number_sold') + 1
>>> product.save()

This approach doesn’t use the initial value from the database. Instead, it makes the database do the update based on whatever value is current at the time that the save() is executed.

Once the object has been saved, you must reload the object in order to access the actual value that was applied to the updated field:

>>> product = Products.objects.get(pk=product.pk)
>>> print product.number_sold
42

For more details, see the documentation on F() expressions and their use in update queries.

Deleting objects

Model.delete([using=DEFAULT_DB_ALIAS])
Django 1.2 で新たに登場しました: The using argument was added.

Issues a SQL DELETE for the object. This only deletes the object in the database; the Python instance will still exist and will still have data in its fields.

For more details, including how to delete objects in bulk, see オブジェクトの削除.

If you want customized deletion behavior, you can override the delete() method. See 既存のモデルメソッドをオーバライドする for more details.

その他のモデルインスタンスメソッド

モデルには、特殊な使われ方をするメソッドがあります:

__unicode__

Model.__unicode__()

__unicode__() メソッドは、オブジェクトに対して unicode() を呼び出し た際に呼び出されます。Django uses unicode(obj) (or the related function, str(obj)) in a number of places. Most notably, to display an object in the Django admin site and as the value inserted into a template when it displays an object. Thus, you should always return a nice, human-readable representation of the model from the __unicode__() method.

For example:

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 任せにするよう勧めます。

__str__

Model.__str__()

The __str__() method is called whenever you call str() on an object. The main use for this method directly inside Django is when the repr() output of a model is displayed anywhere (for example, in debugging output). Thus, you should return a nice, human-readable string for the object’s __str__(). It isn’t required to put __str__() methods everywhere if you have sensible __unicode__() methods.

The previous __unicode__() example could be similarly written using __str__() like this:

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

get_absolute_url

Model.get_absolute_url()

オブジェクトの正統的 (canonical) な URL を演算する方法を Django に教えるには get_absolute_url メソッドを定義してください。To callers, this method should appear to return a string that can be used to refer to the object over HTTP.

例えば:

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

(Whilst this code is correct and simple, it may not be the most portable way to write this kind of method. The permalink() decorator, documented below, is usually the best approach and you should read that section before diving into code implementation.)

Django が get_absolute_url() を使う場面の一例が admin インタフェースの 中にあります。あるオブジェクトがこのメソッドを定義している場合、そのオブジェクト の編集ページには「サイト上で表示 (View on site)」というリンクが表示されます。 このリンク先はオブジェクトの get_absolute_url() から得られる URL になっており、オブジェクトの公開ビューに直接飛べるようになります。

同様に、その他の例えば 配信フィードフレームワーク などが get_absolute_url() を、定義されていれば 使います。もしモデルのインスタンスごとに一意な URL を持つのが自然であるならば、 get_absolute_url() を定義するべきでしょう。

テンプレートでは、オブジェクトの URL をハードコードする代わりに get_absolute_url() を使うよう習慣づけすべきです。例えば、 以下のテンプレートコードは悪い例です:

<!-- BAD template code. Avoid! -->
<a href="/people/{{ object.id }}/">{{ object.name }}</a>

こちらのテンプレートコードの方がもっと良いです:

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

The logic here is that if you change the URL structure of your objects, even for something simple such as correcting a spelling error, you don’t want to have to track down every place that the URL might be created. Specify it once, in get_absolute_url() and have all your other code call that one place.

Note

get_absolute_url() の返す文字列は ASCII 文字だけで構成されている 必要 があります (RFC 2396 の URI 仕様でそのように要求されています)。 また、必要に応じて URL エンコードせねばなりません。

戻り値については、まったく追加処理することなく get_absolute_url() を呼び出すコードやテンプレートからすぐ利用可能であるべきです。 完全に ASCII の範囲に入らない文字を含む Unicode 文字列を使っているのであれば、 django.utils.encoding.iri_to_uri() が役に立つかもしれません。

追加のインスタンスメソッド

save(), delete() に加えて、モデルオブジェクトは 以下メソッドのうちいくつかを持つことがあります:

Model.get_FOO_display()

choices セットを持つ全てのフィールドについて、 オブジェクトは get_FOO_display() メソッドを持ちます。 FOO はフィールド名です。このメソッドは、「人間可読な」フィールド名を返します。 例えば、以下のモデル:

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

では、各 Person インスタンスは get_gender_display() メソッド を持ちます:

>>> p = Person(name='John', gender='M')
>>> p.save()
>>> p.gender
'M'
>>> p.get_gender_display()
'Male'
Model.get_next_by_FOO(**kwargs)
Model.get_previous_by_FOO(**kwargs)

null=True であるような DateField および DateTimeField フィールドについて、オブジェクトは get_next_by_FOO() および get_previous_by_FOO() メソッドを持ちます。 FOO はフィールド名です。このメソッドは該当の日付フィールドに応じて 前のオブジェクトや次のオブジェクトを返します。適切なオブジェクトがなければ DoesNotExist を送出します。

これらのメソッドはいずれもオプションのキーワード引数をとります。引数は 前述の「 Field lookups 」で解説した形式にします。

同じ日付値を持つオブジェクトがある場合、このメソッドは主キーを判断基準として 使います。これにより、レコードがスキップしたり重複したりしないことが 保証されています。また、これらのメソッドを未保存のオブジェクトでは使えないことも 意味しています。