34

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 Serializer を「拡張」して辞書を処理したり、simplejson を「拡張」して Django QuerySet オブジェクトを処理したりできますか?

4

3 に答える 3

39

私は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

于 2010-02-12T10:51:32.753 に答える
13

django でほとんどの構造をシリアル化する非常に柔軟な方法は、ここにあるシリアライザー クラスを使用することです。

于 2011-07-03T13:57:26.027 に答える
10

Clement's answer に基づいて、モデルを 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
于 2010-08-14T20:36:58.317 に答える