JSON serializer をカスタマイズして ensure_ascii が指定されない場合には settings.DEFAULT_SERIALIZE_ENSURE_ASCII をセットするようにしてみました。 着想は Python 温泉 #00 より。
「 custom SQL から fixture に移行してみました 」 でもふれたように、 Django 0.97-pre (rev.5515) の JSON serializer は ensure_ascii = True となっています。 ensure_ascii = False とすれば文字化けを回避できますが、 コマンドラインの manage.py dumpdata では引数を与える手段がありません。
オリジナルの JSON serializer を継承し serialize メソッドが settings.DEFAULT_SERIALIZE_ENSURE_ASCII を扱えるように変更します。 カスタムシリアライザは settings.SERIALIZATION_MODULES に追加します。
utils/serializers/json.py
from django.core.serializers.json import *
from django.conf import settings
class Serializer(Serializer):
def serialize(self, *args, **kargs):
if not "ensure_ascii" in kargs.keys()\
and hasattr(settings, "DEFAULT_SERIALIZE_ENSURE_ASCII"):
kargs.update(dict(ensure_ascii=settings.DEFAULT_SERIALIZE_ENSURE_ASCII))
super(Serializer, self).serialize(*args, **kargs)
settings.py
SERIALIZATION_MODULES = {
"json": "utils.serializers.json"
}
DEFAULT_SERIALIZE_ENSURE_ASCII = False
utils/tests.py
#DEFAULT_SERIALIZE_ENSURE_ASCII
>>> from django.conf import settings
>>> settings.DEFAULT_SERIALIZE_ENSURE_ASCII
False
>>> from django.core import serializers
>>> from michilu.blog.models import Entry
>>> from utils.doctests import loaddata
>>> loaddata("utils/tests/blog.json")
>>> response = serializers.serialize("json", Entry.objects.all(), fields=("content"))
>>> sample = r'[{"pk": "1", "model": "blog.entry", "fields": {"content": "[TEST]: \xe3\x82\xbf\xe3\x82\xa4\xe3\x83\x88\xe3\x83\xab"}}]'
>>> assert(response == sample)
>>> print response
[{"pk": "1", "model": "blog.entry", "fields": {"content": "[TEST]: タイトル"}}]
>>> response = serializers.serialize("json", Entry.objects.all(), ensure_ascii=True, fields=("content"))
>>> sample = r'[{"pk": "1", "model": "blog.entry", "fields": {"content": "[TEST]: \\u00e3\\u0082\\u00bf\\u00e3\\u0082\\u00a4\\u00e3\\u0083\\u0088\\u00e3\\u0083\\u00ab"}}]'
>>> assert(response == sample)
>>> print response
[{"pk": "1", "model": "blog.entry", "fields": {"content": "[TEST]: \\u00e3\\u0082\\u00bf\\u00e3\\u0082\\u00a4\\u00e3\\u0083\\u0088\\u00e3\\u0083\\u00ab"}}]
shell
$ ./manage.py dumpdata --indent=2 blog
[
{
"pk": "1",
"model": "blog.entry",
"fields": {
"content": "[TEST]: タイトル",
"add_date": "2007-06-24 17:26:08",
"tag": [
1
],
"last_mod": "2007-06-24 20:49:01"
}
},
{
"pk": "1",
"model": "blog.tag",
"fields": {
"value": "TEST"
}
}
]
