Saturday, February 26, 2011

Re: How can I control JSON serialization?

Here's a simple copy-paste from some code I wrote yesterday. I'm not sure it's The Right Way of doing things, but it gets the job done.

Assume a model Customer with fields id, name and email.

  # views.py from django.utils import simplejson from django.views.generic.list import ListView
  def customer_serialize(queryset):     if isinstance(queryset[0], Customer):         result = []         last_find = 0         for customer in queryset:             result += [dict(id=customer.id, name=customer.name, email=customer.email), ]         return result     else:         raise TypeError(repr(queryset) + " is not JSON serializable or isn't a valid Customer queryset.")
  class CustomerSearch(ListView):     model = Customer     slug_field = 'email'     context_object_name = 'customers'     template_name = 'customer/index.html'          def get_queryset(self):         self.queryset = self.model.objects.filter(email__startswith=self.kwargs['slug'])         return self.queryset              def get(self, context, **kwargs):         # the important bits         if self.request.is_ajax():             result = customer_serialize(self.get_queryset())             return HttpResponse(                             simplejson.dumps(result),                             mimetype='application/json',                             )                      return super(CustomerSearch, self).get(context, **kwargs) 

I hope that helps! My code is a little different, in reality, so forgive me for any typos as I didn't really test this.


Sincerely,
Andre Terra

On Sat, Feb 26, 2011 at 6:30 PM, Alexander Bolotnov <abolotnov@gmail.com> wrote:

Is there a way to control json serialization in django? Simple code below will return serialized object in json:

  co = Collection.objects.all()
c
= serializers.serialize('json',co)

The json will look similar to this:

  [
   
{
       
"pk": 1,
       
"model": "picviewer.collection",
       
"fields": {
           
"urlName": "architecture",
           
"name": "\u0413\u043e\u0440\u043e\u0434 \u0438 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430",
           
"sortOrder": 0
       
}
   
},
   
{
       
"pk": 2,
       
"model": "picviewer.collection",
       
"fields": {
           
"urlName": "nature",
           
"name": "\u041f\u0440\u0438\u0440\u043e\u0434\u0430",
           
"sortOrder": 1
       
}
   
},
   
{
       
"pk": 3,
       
"model": "picviewer.collection",
       
"fields": {
           
"urlName": "objects",
           
"name": "\u041e\u0431\u044a\u0435\u043a\u0442\u044b \u0438 \u043d\u0430\u0442\u044e\u0440\u043c\u043e\u0440\u0442",
           
"sortOrder": 2
       
}
   
}
]

You can see it's serializing it in a way that you are able to re-create the whole model, shall you want to do this at some point - fair enough, but not very handy for simple JS ajax in my case: I want bring the traffic to minimum and make the whole thing little clearer.

What I did is I created a view that passes the object to a .json template and the template will do something like this to generate "nicer" json output:

  [
{% if collections %}
   
{% for c in collections %}
{"id": {{c.id}},"sortOrder": {{c.sortOrder}},"name": "{{c.name}}","urlName": "{{c.urlName}}"}{% if not forloop.last %},{% endif %}
   
{% endfor %}
{% endif %}
]

This does work and the output is much (?) nicer:

  [
   
{
       
"id": 1,
       
"sortOrder": 0,
       
"name": "Город и архитектура",
       
"urlName": "architecture"
   
},
   
{
       
"id": 2,
       
"sortOrder": 1,
       
"name": "Природа",
       
"urlName": "nature"
   
},
   
{
       
"id": 3,
       
"sortOrder": 2,
       
"name": "Объекты и натюрморт",
       
"urlName": "objects"
   
}
]

However, I'm bothered by the fast that my solution uses templates (an extra step in processing and possible performance impact) and it will take manual work to maintain shall I update the model, for example.

I'm thinking json generating should be part of the model (correct me if I'm wrong) and done with either native python-json and django implementation but can't figure how to make it strip the bits that I don't want.

One more thing - even when I restrict it to a set of fields to serialize, it will keep the id always outside the element container and instead present it as "pk" outside of it.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment