Django オブジェクトのシリアライズ
| revision-up-to: | 7193 (0.97pre SVN) |
|---|
Note
この API は現在まだ開発のまっただなかにあり,おそらく将来劇的に変化する でしょう.
注意してください.
Django の整列化フレームワークを使うと, Django オブジェクトを他の形式に「翻 訳」できます.通常,こうした形式はテキストベースで, Django オブジェクトを ネットワーク越しに伝送するために使われますが, Django のシリアライザは任意 の形式 (テキストベースもそうでないものも) 扱えます.
データのシリアライズ
高水準では,データのシリアライズは極めて簡単な操作です:
from django.core import serializers
data = serializers.serialize("xml", SomeModel.objects.all())
serialize 関数の引数には,データのシリアライズに使うフォーマット (シリアライズの形式 参照) と,シリアライズ対象の QuerySet を指定します (実際には,第二引数は Django オブジェクトを返す任意のイテレータにできますが, 大抵の場合は QuerySet を使うことになるでしょう).
シリアライザオブジェクトを直接使ってもかまいません:
XMLSerializer = serializers.get_serializer("xml")
xml_serializer = XMLSerializer()
xml_serializer.serialize(queryset)
data = xml_serializer.getvalue()
シリアライザオブジェクトを直接使うと,以下のようにファイルライクオブジェク ト (もちろん HTTPResponse も使えます) に対して直接シリアライズできるので便 利です:
out = open("file.xml", "w")
xml_serializer.serialize(SomeModel.objects.all(), stream=out)
一部のフィールドだけをシリアライズする
一部のフィールドだけをシリアライズしたい場合には,シリアライザに fields 引数を指定します:
from django.core import serializers
data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))
上の例では, name と size だけがシリアライズされます.
Note
モデルによっては,フィールドの一部だけをシリアライズすると,そこからデ シリアライズできない場合があります.シリアライズ後のオブジェクトに,モ デル上で必須のフィールドがひとつでも抜け落ちていると,デシリアライザは デシリアライズ後のインスタンスを保存できないでしょう.
データのデシリアライズ
データのデシリアライズもまた,かなり単純な操作です:
for obj in serializers.deserialize("xml", data):
do_something_with(obj)
見ての通り, deserialize 関数は serialize 関数と同様,文字列または データストリームを引数にとり,イテレータを返します.
しかしながら,少しだけややこしい部分もあります. deserialize イテレータ の返すオブジェクトは単純な Django オブジェクト ではなく , DeserializedObject という特殊なインスタンスです.このインスタンスは 作成されただけでまだ保存されていないデータであり,リレーションも張られてい ません.
DeserializedObject.save() を呼び出すと,データベースにオブジェクトを保 存します.
上のような仕様から,デシリアライズは,たとえシリアライズされていたデータの 表現形式が現在のデータベースの構成と一致していなかったとしても非破壊的な操 作になるよう保証されています.通常, DeserializedObject インスタンスの 操作は以下のように行います:
for deserialized_object in serializers.deserialize("xml", data):
if object_should_be_saved(deserialized_object):
deserialized_object.save()
すなわち,デシリアライズしたオブジェクトを保存する場合,前もって保存に適し ているかどうかを調べるのが普通のやり方なのです.もちろん,データソースを信 頼できるのなら,単にデータを保存してもかまいません.
Django オブジェクト自体に対するインスペクションは, deserialized_object.object で行えます.
シリアライズの形式
Django には各種形式のシリアライザが付属しています:
名前 情報 xml 単純な XML シリアライザです. json JSON シリアライザ (Django に付属の simplejson を使ったも の) です. python 「単純な」Python オブジェクト (リスト,辞書,文字列など) の シリアライザです.単体では取り立てて便利ではありませんが, 他のシリアライザのベースになっています. yaml YAML (Yet Another Markup Language) へのシリアライザです. このシリアライザは PyYAML がインストールされている場合のみ 利用できます.
各シリアライズ形式についての注意
json
UTF-8 (や,非 ASCII エンコーディング) でエンコードされたデータを JSON シリ アライザで扱うには, serialize() のパラメタに ensure_ascii=False を 指定してください.さもないと,出力のエンコードがおかしくなってしまいます.
例:
json_serializer = serializers.get_serializer("json")()
json_serializer.serialize(queryset, ensure_ascii=False, stream=response)
Django のソースコードには simplejson モジュールが付属しています。注意して ほしいのは、このモジュールを直接使ってシリアライズを実行すると、一部の Django オブジェクトは何らかの変更が加えられた上で simplejson に渡されてしま うということです。特に、 遅延翻訳オブジェクト をシリアライズする場合は、 特殊なエンコーダ が必要です。以下のように書くと、うまくいくでしょう:
from django.utils.functional import Promise
from django.utils.encoding import force_unicode
class LazyEncoder(simplejson.JSONEncoder):
def default(self, obj):
if isinstance(obj, Promise):
return force_unicode(obj)
return obj