先週、 Django 1.2 が出ました。新しくて、良い機能がいっぱい入っているけども、1.1 からの変更をご紹介しようかと思っています。
マルチDB
1.2 では、一番大きい変更は明らかに
マルチDB対応
ですね。 settings.py
の DATABASE
オプションは DATABASES
になりました。それで python
辞書で複数のDBを設定する。
以下のように MySQL、sqlite、PostgreSQL、それぞれ違ってても構いません。
DATABASES = {
'default': {
'NAME': 'app_data',
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'USER': 'postgres_user',
'PASSWORD': 's3krit'
},
'users': {
'NAME': 'user_data',
'ENGINE': 'django.db.backends.mysql',
'USER': 'mysql_user',
'PASSWORD': 'priv4te'
}
}
どのデータベースをどの場合に使うかをデータベースルータで決める。 モデルの読み込みの場合のDB、書き込みの場合のDB、リレーションを許可するかどうか、syncdb (テーブル定義)の許可を実装する。
class MyAppRouter(object):
"""myappアプリケーションのモデルを別DBに保存し、
DBの操作を制御する"""
def db_for_read(self, model, **hints):
"'myapp'の場合、'other'というDBを使う。"
if model._meta.app_label == 'myapp':
return 'other'
return None
def db_for_write(self, model, **hints):
"'myapp'の場合、'other'というDBを使う。"
if model._meta.app_label == 'myapp':
return 'other'
return None
def allow_relation(self, obj1, obj2, **hints):
"両方のモデルが'myapp'に入っている場合のみにリレーションを許可"
if obj1._meta.app_label == 'myapp' or obj2._meta.app_label == 'myapp':
return True
return None
def allow_syncdb(self, db, model):
"'myapp' を 'other' DB のみに入れるようにする。"
if db == 'other':
return model._meta.app_label == 'myapp'
elif model._meta.app_label == 'myapp':
return False
return None
モデル検証
モデルのデータを検証すること ができるようになりました。それに、新しいモジュール django.core.validators ができました。
フォームと同じように full_clean()
, clean_fields()
, clean()
,
validate_unique()
の 4つのメソッドが追加されました。
clean_fields(exclude=None)
を呼び出すとモデルのフィールドのデータを一個一個検証する。
clean()
はカスタム検証の処理を実装するためのメソッド。このメソッドをサブクラスで実装すれば、カスタム検証ができます。
validate_unique(exclude=None)
はユニークフィールドの検証を行う。
full_clean(exclude=None)
を呼び出すとすべての検証を行います。
exclude
パラメーターで検証を行わないフィールドを指定できる。
CSRF 対策
1.1の CsrfMiddleware は正規表現でCSRF用フィールドをフォームに突っ込むことができたが、実装が微妙でJSなどに使えなかったので、Django 1.2でもっと綺麗なAPIが揃えました
django.middleware.csrf.CsrfViewMiddleware
が新しくできました。 このミードールウエアでCSRFのトーケンが生成され、ポストの場合、検証が行われ {% csrf_token %}
テンプレートタグでフォームに入れることができている。
Middleware を使いたくない場合は、 CSRF対策をしたい viewのみに
django.views.decorators.csrf.csrf_protect
デコレータを使うことができます。
messages API
以前、Djangoのユーザメッセージは 「変更しました」とか、「削除しました」とか、一時的なメッセージなのに DB に保存しましたので、微妙だった。
それで、Django 1.2 では新しい messages API ができました。 DB のかわりにセキュアクッキーとセッションを使えるようになりました。後、メッセージタイプ、info、warning、errorなどが使えるようになりました。
from django.contrib import messages
messages.add_message(request, messages.INFO, 'Hello world.')
messages.success(request, u'プロフィールを更新しました。')
messages.warning(request, u'サービス契約が後3日で切ります。')
messages.error(request, u'レコードが削除されました')
メールバックエンド
クラウドサービスでは、メールがAPI で提供されているのが多くて、Django 1.1 では send_mail
は使えなかったんですけど、
Django 1.2では
メールバックエンド
が使えるようになりました。
標準に入っているのは、SMTP、コンソールに出力するのみ、メールを無視するバックエンドが揃えている。
カスタムバックエンドを作るために、 django.core.mail.backends.base.BaseEmailBackend
を継承して、 send_messages(email_messages)
を実装する。 永続コネクションを使う時は
open()
と close()
メソッドを実装すれば良い。
smart if テンプレートタグ
Django 1.1 以前では、 if テンプレートタグは boolean しか使えなくて、複雑なコンディションが書けなかった。 Django
1.2 から、 ==
、 >
、 <
、 and
、 or
などが使えれるようになりました。
{% if a != b %}
...
{% if c == d and e >= f %}
...
{% endif %}
...
{% endif %}
まとめ
ちょっとしたバグのため、Django 1.2.1 がすぐ出ると思いますが、Django 1.2 は良い新規機能が多くて、是非使って見てください。