Simplejsonを使用してDjangoモデルをシリアル化します。Djangoのシリアライザは辞書をサポートしていません...およびsimplejsonはDjangoクエリセットをサポートしていません。これはかなり難問です。
モデルには、スポンサーレベルへの外部キーを持つスポンサーがあり、特定のスポンサーレベルに属するすべてのスポンサーをグループ化しようとしています。リストを生成するコードは次のとおりです。
from Django.shortcuts import get_list_or_404
from special_event.models import Sponsor, SponsorLevel
sponsor_dict = {}
roadie_sponsors = get_list_or_404(Sponsor, level__category = SponsorLevel.ROADIE_CHOICE)
for item in roadie_sponsors:
try:
sponsor_dict[item.level.name].append(item)
except KeyError:
sponsor_dict[item.level.name] = [item]
これがsponsor_dict
は「作成」されたように見えます
{
'Fan': [<Sponsor: Fan Sponsor>],
'VIP': [<Sponsor: VIP Sponsor>],
'Groupie': [<Sponsor: Groupie Sponsor>],
'Silver': [<Sponsor: Silver Sponsor>],
'Bronze': [<Sponsor: Another Bronze Sponsor>, <Sponsor: Bronze Sponsor>]
}
ブロンズを除いて、各レベルにスポンサーを1人だけ追加しました。私がやりたいのは、それをJSONに「すべて」入れて、jQueryが簡単に解釈できるようにすることです。 Djangoの他のシリアライザ(XMLやYAMLなど)はこれを実現できますか? Django辞書を処理するJSONシリアライザーを「拡張」したり、Django QuerySetオブジェクトを処理するようにsimplejsonを「拡張」したりできますか?
simplejsonを拡張していきます。基本的には、JSONエンコーダーがQuerySetに遭遇したときにDjangoのシリアル化をプラグインする必要があります。あなたは次のようなものを使うことができます:
from json import dumps, loads, JSONEncoder
from Django.core.serializers import serialize
from Django.db.models.query import QuerySet
from Django.utils.functional import curry
class DjangoJSONEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, QuerySet):
# `default` must return a python serializable
# structure, the easiest way is to load the JSON
# string produced by `serialize` and return it
return loads(serialize('json', obj))
return JSONEncoder.default(self,obj)
# partial function, we can now use dumps(my_dict) instead
# of dumps(my_dict, cls=DjangoJSONEncoder)
dumps = curry(dumps, cls=DjangoJSONEncoder)
default
メソッドの詳細については、 simplejsonのドキュメント を参照してください。これをpythonモジュールに入れてから、dumps
をインポートすれば問題ありません。ただし、この関数はQuerySet
インスタンスのシリアル化にのみ役立つことに注意してください。 Model
インスタンスを直接ではありません。
Django=のほとんどの構造をシリアル化する本当に柔軟な方法は、見つかったシリアライザクラスを使用することです here
clementの回答に基づいて、モデルをJSONに変換するためにもこれを行いました。
def toJSON(obj):
if isinstance(obj, QuerySet):
return simplejson.dumps(obj, cls=DjangoJSONEncoder)
if isinstance(obj, models.Model):
#do the same as above by making it a queryset first
set_obj = [obj]
set_str = simplejson.dumps(simplejson.loads(serialize('json', set_obj)))
#eliminate brackets in the beginning and the end
str_obj = set_str[1:len(set_str)-2]
return str_obj