Django オンラインドキュメント和訳 更新しました。 Revision 5613 (2007/07/05). Unicode branches がマージされました。
以下、 diff -r 5583:5613 の主な変更分です。
開発版の Django で新たに追加された機能です
Django はネイティブで Unicode データをサポートしています.データベースの設 定を正しく行っている限り,テンプレートやモデル,データベース間で Unicode 文 字列を問題なく受渡しできます.
(以下、略。本文 Django での Unicode の扱い を参照してください。)
おっと,ちょっと待って下さい. <Poll: Poll object> なんて全然親切な表現 ではありませんね.そこで (polls/models.py ファイルに定義されている) polls 関係のモデルを少し修正して, Poll と Choice に __unicode__() メソッドを追加しましょう
class Poll(models.Model):
# ...
def __unicode__(self):
return self.question
class Choice(models.Model):
# ...
def __unicode__(self):
return self.choice
__unicode__() をモデルに追加しておくのは,対話プロンプトで扱うときに精 神的によいだけでなく,オブジェクトの表現 (representation) は Django 自動 admin のいたるところで使われているという点でも重要です.
なぜ __str__() ではなく __unicode__() を使うの?
Python に詳しければ,普段は __str__() ではなく __unicode__() を 実装していることでしょう. __unicode__() を使うのは, Django のモデ ルがデフォルトで Unicode を扱うようになっているからです. Django では, データベース上に保存された文字列の情報は,取り出すときに全て Unicode 型 に変換されます.
Django のモデルは,デフォルトで __str__() メソッドを実装していて, 中で __unicode__() を呼び出して,得た結果を UTF-8 のバイト文字列に 変換しています.従って, unicode(p) は Unicode 文字列を返し, str(p) は UTF-8 でエンコードされた通常の文字列を返します. この仕様がよくわからなければ,とにかく __unicode__() をモデルに追加 するのだと覚えておいてください.なにはともあれ,それでうまく動作します.
__unicode__() は通常の Python メソッドということに注意してください.
モデルの内部クラスや標準メソッドの順番は以下のようにします (ただし, どれも必須ではないので省略してもかまいません):
- 全てのデータベースフィールド
- class Meta
- class Admin
- def __unicode__()
- def __str__()
- def save()
- def get_absolute_url()
- カスタムのメソッド定義
開発バージョンの Django で新たに追加されました
デフォルト値: 'utf-8'
テンプレートファイルや SQL のデータファイルなどのファイルをファイルシステム から読み出すときに使う文字エンコーディングです.
__str__() および __unicode__() メソッドは他のモデルメソッドと 同じように list_display に入れられるので,以下のように書いても全 く問題ありません
list_display = ('__unicode__', 'some_other_field')
__str__() は,オブジェクトに対して str() を呼び出した際に返す内容を 定義するための Python の特殊メソッドです. Django はそこかしこで str(obj) (または unicode(obj) -- 下記参照) を使っています.ほとんど は, Django の admin サイトでオブジェクトをレンダリングして表示したときの値 として,またオブジェクトを表示するときにテンプレートに挿入される値として使 われています.従って,オブジェクトの``__str__`` は,人間可読なわかりやすい 文字列を返さねばなりません.必須ではありませんが,強く推奨します (ただし, そこかしこに __str__ メソッドを突っ込んでしまう前に __unicode__ の 説明を良く読んでくださいね).
例えば
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=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() を呼び出し た際に呼び出されます.Django のデータベースバックエンドはモデルの属性値とし て Unicode 文字列を返すので,通常はモデルの __unicode__() メソッドを定 義するとよいでしょう.前節の例を __unicode__() を使って書き直すと,以下のように簡単になります
class Person(models.Model):
first_name = models.CharField(maxlength=50)
last_name = models.CharField(maxlength=50)
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
モデルに __unicode__() メソッドだけを定義して, __str__() は定義し ないでおくと, Django が自動的に __str__() メソッドをモデルに追加します. この __str__() メソッドは, __unicode()__ を呼び出して,その戻り値 を UTF-8 でエンコードした文字列を返します.開発上はこの仕様に従い, __unicode__() だけを定義して,文字列オブジェクトへの変換は Django 任せにするよう勧めます.
Note
get_absolute_url() の返す文字列は ASCII 文字だけで構成しなければな りません (RFC 2396 の URI 仕様でそのように要求されています).また, 必要に応じて URL エンコードせねばなりません. get_absolute_url() を 使うコードやテンプレートが, get_absolute_url() の返す文字列を,追 加の処理を施さなくても直接利用できるようにせねばならないのです. URI に Unicode 文字列を沢山使っているのなら, django.utils.encoding.iri_to_uri も使うことになるでしょう.
翻訳対象文字列を関数 ugettext() で指定します.タイプ数を減らすため, ugettext() を _ という別名で import するのが慣習的なやり方です.
Note
Python の標準ライブラリ gettext は,グローバルの名前空間に _() という名前で gettext() をインストールします. Django ではこの方法に 従っていませんが,それは以下の理由からです:
- 国際化文字セット (Unicode) のサポート下では, gettext() よりも ugettext() の方が便利だからです.また,ファイルによっては ugettext_lazy() をデフォルトの翻訳用メソッドに使った方がよい 場合もあります.グローバル名前空間に _() がなければ,開発者に 場合に応じて適切な翻訳用メソッドを選ぶ自由を与えられます.
- アンダースコア文字は, Python の対話シェルや doctest で書かれたテ スト中では「直前の式の値」を表します.そのため,グローバル名前空間 に _() をインストールすると,干渉して問題を引き起こします. ugettext() を _() という名前で明示的に import すれば,こ の問題を回避できます.
モデルやユーティリティ関数では, ugettext_lazy() や ungettext_lazy() を使って文字列をマークすることがよくあります.こうして マークした文字列をコードの他の部分で扱うときには,マークしてできた遅延翻訳 オブジェクトをうっかり文字列に変換してしまわないよう気を付けてください.遅 延翻訳オブジェクトの変換は (ロケールの影響下に入るように) できるだけ遅くせ ねばならないからです.遅延翻訳オブジェクトの変換を遅らせるために,以下の二 つのヘルパ関数があります.
標準の Python 文字列型の join メソッド (''.join([...])) は,遅延翻訳オ ...ブジェクトの入ったリストをうまく扱えません.その代わり, django.utils.translation.string_concat() を使ってください.このメソッド は,全ての内容を結合し, かつ 文字列中に値が取り込まれるまで実際に変換を 行わないような遅延オブジェクトを生成して返します.例えば
from django.utils.translation import string_concat
...
name = ugettext_lazy(u'John Lennon')
instrument = ugettext_lazy(u'guitar')
result = string_concat([name, ': ', instrument])
上のケースでは, result 中の遅延翻訳オブジェクトは, result 自体を 文字列中で使った場合 (テンプレートのレンダリング時など) にしか文字列に変換 されません.
Django はたくさんのユーティリティ関数を (とりわけ django.utils パッケー ジで) 提供しています.これらの関数の多くは文字列を第一引数にとり,文字列に 対して何らかの処理を行います.関数はテンプレートフィルタ内で使われたり,他 のコードで直接呼び出されたりしています.
同様の関数を自分で作成し,翻訳文字列を扱おうとした場合,第一引数が遅延翻訳 オブジェクトの場合に問題に直面することでしょう.この関数はビューの外側 (つ まり,現在のスレッドのロケール設定が的確でないかもしれない場所) で使われる かもしれないので,関数内で遅延翻訳オブジェクトを文字列に変換したくないはず だからです.
こうした場合のために, django.utils.functional.allow_lazy() デコレータ を使ってください.このデコレータで関数をラップすると,関数の第一引数に遅延 翻訳オブジェクトを渡した場合,関数の評価を文字列に変換する瞬間まで遅延させ られます.
例を示しましょう
from django.utils.functional import allow_lazy
def fancy_utility_function(s, ...):
# Do some conversion on string 's'
...
fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
allow_lazy() デコレータは関数名に加えて追加の引数 (*args) をとりま す.この引数には,デコレーション対象の関数の戻り値の型 (複数可) を指定しま す.通常は, unicode だけを入れておき,関数が必ず Unicode 文字列を返す ようにしておけばよいでしょう.
このデコレータを使えば,適切な文字列を入力として受け取る関数を書いておき, 後で遅延翻訳オブジェクトのサポートを追加できます.
IRI (国際化リソース識別子 Internationalized Resource Identifier) を URL 埋め込みに適した文字列に変換します.非 ASCII 文字列を URL に埋め込む 場合に必要なフィルタです.
urlencode フィルタを通した文字列をこのフィルタに通しても問題はありません.
