revision-up-to: | 17812 (1.4) unfinished |
---|
このドキュメントでは、モデル API の詳細を解説します。このドキュメントは、 モデル や データベースクエリ といったガイドを前提にしているので、このドキュメントを 読む前に、予め読んで理解しておくとよいでしょう。
このリファレンスでは、 データベースクエリガイド の Weblog のモデル例 を使います。
モデルの新たなインスタンスは、通常の Python のクラスと同じ方法で生成します:
Model
(**kwargs)¶キーワード引数に指定できる名前は、モデルで定義したフィールドの名前です。
モデルのインスタンスを生成しても、 save()
を呼び出すまで
データベースは操作されません。
リリースノートを参照してください
There are three steps involved in validating a model:
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])¶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 は以下の段階を踏んでオブジェクトを保存します:
pre_save シグナルの発行
django.db.models.signals.pre_save
シグナル
の発行によって、何らかのオブジェクトを保存しようとしていることを通知
します。このシグナルを待ち受けている関数でカスタムの処理を実行できます。
データの前処理 オブジェクトの各フィールドについて、保存時に自動的に 実行する必要があるデータ修飾処理がないか調べ、あれば実行します。
ほとんどのフィールドは前処理を 伴いません 。フィールドのデータはそのまま
保存されます。前処理が行われるのは、特殊な挙動を示すフィールドだけです。
例えば、 auto_now=True
に設定された DateField
の場合、前処理の段階で、フィールドの内容が現在の日付になるようデータを
置き換えます (現時点では、「特殊な」挙動を示すフィールドのリストを
全て列挙したドキュメントはありません)。
データベース保存用のデータ準備処理 各フィールドについて、フィールドの 現在の値を元にデータベースに保存できる型のデータを生成します。
ほとんどのフィールドはデータ準備処理を 伴いません 。整数や文字列は Python オブジェクトとして「いつでもデータベースへの書き込みに使える」 形式になっています。ただ、より複雑なデータ型の場合、なにがしかの修飾 が必要なことがあります。
例えば、 DateField
は、データの保存に Python の
datetime
型を使います。データベースは datetime
オブジェクトを
保存しないので、データベースに保存するには、フィールドの値を ISO
準拠の日付文字列に変換せねばなりません。
データベースへの保存 前処理と準備処理を経たデータが SQL 文に組み込まれ、 データベースに挿入されます。
post_save シグナルの発行
django.db.models.signals.pre_save
シグナルと同じく、オブジェクトが
成功理に保存されたことを通知するために
django.db.models.signals.post_save
シグナルが発行されます。
Django データベースオブジェクトがオブジェクトの作成と変更に同じ save()
メソッドを使っていることにお気づきかもしれませんね。 Django は INSERT
と UPDATE
SQL 文のどちらを使うべきかの判断を抽象化しています。具体的
に言うと、 save()
を呼び出したときに、Django は以下のアルゴリズムに従い
ます:
False
でない場合 (None
や
空文字列の場合などでない場合) 、 Django は SELECT
クエリを使って、
該当する主キーを持つレコードが存在するかどうか調べます。UPDATE
クエリを使います。INSERT
を使います。新たなオブジェクトを保存する際、まだ使われていない値を主キーに指定できる保 証がないかぎり、主キーの値を明示的に指定しないよう注意してください。詳しく は上記の 自動主キーの値を明示的に指定する の節や、後述の INSERT や UPDATE を強制する を参照してください。
ごく稀に、 save()
メソッドに INSERT
だけを実行させ、
UPDATE
にフォールバックさせたくない、あるいはその逆、すなわち UPDATE
が可能なら実行するが、新たなレコードの INSERT
はさせたくないような場合が
あります。そんなときには、 force_insert=True
や force_update=True
パラメタを save()
メソッドに渡してください。
明らかなことではありますが、INSERT
と UPDATE
は同時に行えないので、
両方のパラメタを同時に渡すとエラーを引き起こします。
このパラメタが必要なケースは本当にごく稀な場合だけです。たいていは、 Django は正しい SQL で保存を行いますし、パラメタをオーバライドすると、追跡の困難な エラーにつながる恐れがあります。特殊な用途でだけ、このパラメタを使ってくだ さい。
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.
Model.
delete
([using=DEFAULT_DB_ALIAS])¶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()
が役に立つかもしれません。
permalink
デコレータ¶上に述べた get_absolute_url()
を使う方法は、少し DRY 則を侵犯しています。
このオブジェクトの URL が URLconf ファイルとモデルの両方で定義されているからです。
permalink
デコレータを使うと、 URLconf からモデルを脱カップリングできます:
permalink
()¶This decorator takes the name of a URL pattern (either a view name or a URL pattern name) and a list of position or keyword arguments and uses the URLconf patterns to construct the correct, full URL. It returns a string for the correct URL, with all parameters substituted in the correct positions.
The permalink
decorator is a Python-level equivalent to the url
template tag and a high-level wrapper for the django.core.urlresolvers.reverse()
function.
An example should make it clear how to use permalink()
. Suppose your URLconf
contains a line such as:
(r'^people/(\d+)/$', 'people.views.details'),
また、モデルの get_absolute_url()
メソッドは以下のように定義できます:
from django.db import models
@models.permalink
def get_absolute_url(self):
return ('people.views.details', [str(self.id)])
また、以下のような URLconf のエントリがあったなら:
(r'/archive/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/$', archive_view)
以下のように permalink()
を使ってこれを参照できます:
@models.permalink
def get_absolute_url(self):
return ('archive_view', (), {
'year': self.created.year,
'month': self.created.strftime('%m'),
'day': self.created.strftime('%d')})
この例では、第 2 引数に空の配列 (空のタプル) を指定していますが、これは引数 リストを渡さず、キーワード引数だけを渡したいからです。
この方法では、ビューの URL に関する情報を繰り返すことなく、モデルの
絶対パスと表示に使ったビューを結びつけられます。以前と同様、
get_absolute_url()
はテンプレート中でも使えます。
汎用ビューを使う場合や、複数のモデルに対して同じビューを再利用する場合、ビュー
関数そのものを指定すると、(複数のパターンが同じビューを指してしまうため)
URLディスパッチャが混乱をきたします。
その場合、 Django には 名前つき URL パターン
があります。名前つき URL パターンを使えば、 URL パターンに固有の名前をつけておき、
ビュー関数の代わりに参照できます。名前つき URL パターンを定義するには、
タプル表記の URL パターンを url
関数に置き換えます:
from django.conf.urls import patterns, url, include
url(r'^people/(\d+)/$', 'blog_views.generic_detail', name='people_view'),
この名前を使って、URL からビューの名前を以下のようにして逆解決します:
from django.db import models
@models.permalink
def get_absolute_url(self):
return ('people_view', [str(self.id)])
名前つき URL パターンの詳細については URL ディスパッチャのドキュメント を参照してください。
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 」で解説した形式にします。
同じ日付値を持つオブジェクトがある場合、このメソッドは主キーを判断基準として 使います。これにより、レコードがスキップしたり重複したりしないことが 保証されています。また、これらのメソッドを未保存のオブジェクトでは使えないことも 意味しています。
Oct 26, 2017