[Django]: 文字化けしない JSON serializer

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"
    }
  }
]

http://MiCHiLU.com/blog/posts/87/

  • Added at Sun, 24 Jun 2007 20:46:15 +0900
  • Last modified at Sun, 24 Jun 2007 21:09:23 +0900

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 2.1 Japan License. http://creativecommons.org/licenses/by-nc-sa/2.1/jp/

author:
Posted on
Updated on