JSON Serializing Django Models with simplejson

2019-01-16 03:03发布

I'd like to use simplejson to serialize a Django model. Django's serializer doesn't support dictionaries... and simplejson doesn't support Django Querysets. This is quite a conundrum.

In the model there's sponsors that have a Foreign Key to sponsor level, I'm trying to group all the sponsors that belong to a certain sponsor level together. Here's the code that generates the list:

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]

Here's what sponsor_dict looks like once it's "made"

{
    'Fan': [<Sponsor: Fan Sponsor>], 
    'VIP': [<Sponsor: VIP Sponsor>],
    'Groupie': [<Sponsor: Groupie Sponsor>],
    'Silver': [<Sponsor: Silver Sponsor>],
    'Bronze': [<Sponsor: Another Bronze Sponsor>, <Sponsor: Bronze Sponsor>]
}

I only added one sponsor in each level, except for bronze, just to show how it works. All I want to do is get it "all" into JSON so jQuery can interpret it easily. Can Django's other serializers (like XML or YAML) accomplish this? Can I "extend" the Django JSON Serializer to handle dictionaries or "extend" simplejson to handle Django QuerySet objects?

3条回答
我只想做你的唯一
2楼-- · 2019-01-16 03:37

I would go with extending simplejson. Basically, you want to plug in django's serialization when the JSON encoder encounters a QuerySet. You could use something like:

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)

For more info on default method, have a look at simplejson documentation. Put that in a python module, then import dumps and you're good to go. But note that this function will only help you serializing QuerySet instances, not Model instances directly.

查看更多
【Aperson】
3楼-- · 2019-01-16 03:40

A really flexible way to serialize most structures in django is to use the serializer class found here

查看更多
成全新的幸福
4楼-- · 2019-01-16 03:40

based on Clement's answer, I did this to get models into JSON as well.

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
查看更多
登录 后发表回答