JSON Serializing Django Models with simplejson
Solution 1
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.
Solution 2
A really flexible way to serialize most structures in django is to use the serializer class found here
Solution 3
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
Zack
Updated on July 09, 2022Comments
-
Zack almost 2 years
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?
-
Pickels over 13 yearsIf you have a question you need to click the 'ask question' button at the top right. The 'Your Answer' form is used to post answers.
-
jcage over 13 yearsMy apologies. I only intended it to compliment the topic, since the main answer makes note of its inability to serialize objects. This goal is accomplished, since the code does work. My question about it being a good a idea or bad one was meant to invite discussion about better integration, and certainly not anyone's scorn
-
Glycerine over 12 yearsJust implemented this. It's Brilliant! This script deserves more recognition.
-
stormlifter about 12 yearsThis is a very simple and adaptable solution.
-
Alison R. over 11 yearsCurious to see this based upon the comments, but the page is gone. Anyone know if this is still around anywhere?
-
Nate Pinchot about 11 years