2

What is the best way to accept a nested json object in a django view ?

The request

$.ajax({
   type: 'POST',
   url: 'results/' + self.id + '/',
   contentType:"application/json; charset=utf-8",
   data: JSON.stringify(values),
   dataType:"json",
   ...

values is a javascript dictionary object.

Object {Cart: Array[2], Di: "5"}
  Cart: Array[2]
    0: Object
      N: 1
      PR: 0.75
      __proto__: Object
    1: Object
      N: "2"
      PR: 2.5
      __proto__: Object
  length: 2
  __proto__: Array[0]
  Di: "5"

The view

def do_something(request,pid):
    print json.loads(request.body)

This is the raw post data

{"Cart":["{\"PR\":4,\"N\":1}","{\"PR\":1.2,\"N\":\"2\"}"],"Di":"5"}

The problem is that json.loads leaves the inner dicts in the Cart array as unicode objects.

I've tried using jsonpickle and the old simplejson but i'm getting the same results.

This seem pretty basic - Is there a simple solution for this ?

EDIT

After reading your posts I understand it might be a client side issue but I'm still stringifying the json data only once in the ajax call.

This is how i generate values

The basic case - simple Dict

self.serialized_value = function() {
        if (self.value()) {
           var d = {}
           d[self.name] = self.value();
           return (d);
        }
    };

For object containing several parameters

self.get_serialized_values = function() {
        var values = {};
        $.map(self.parameters(), function(p) {
            $.extend(values, p.serialized_value());
        });
        return values;
    };

For object that contain other objects

 self.serialized_value = function() {
        var child_data = [];
        $.each(self.items() , function(k,v) { 
            child_data.push(v.get_serialized_values());
        });
        var d = {}
        d[self.name] = child_data;
        return (d);
    };

And finally, JSON.stringify is applied only in the ajax call

..
data: JSON.stringify(self.get_serialized_values())
..

Where in the code is the json being stringified twice ?

3
  • json.loads can handle nested objects, I guess it was not serialized correctly on the client side. are you sure you called JSON.stringify on the object as it is you posted, and you didn't serialize its nested parts manually before you serialized the whole object itself? Commented Oct 25, 2013 at 16:36
  • The raw post data is embedding JSON in JSON. Ick! The Cart list consists of two strings that themselves need decoding. What in heavens name is producing this? Commented Oct 25, 2013 at 16:38
  • I added my code for generating Cart. Commented Oct 25, 2013 at 18:41

2 Answers 2

3

That's an issue on the client side. You are serializing twice:

good

var x = { PR: 4, N: 1 };
var cart = { Cart: [x] };
JSON.stringify(cart);

bad (produces your issue)

var x = { PR: 4, N: 1 };
var cart = { Cart: [JSON.stringify(x)] };
JSON.stringify(cart);
Sign up to request clarification or add additional context in comments.

Comments

2

Your posted data contains doubly encoded JSON data:

>>> import json
>>> data = {"Cart":["{\"PR\":4,\"N\":1}","{\"PR\":1.2,\"N\":\"2\"}"],"Di":"5"}
>>> data['Cart']
['{"PR":4,"N":1}', '{"PR":1.2,"N":"2"}']
>>> data['Cart'][0]
'{"PR":4,"N":1}'
>>> json.loads(data['Cart'][0])
{u'PR': 4, u'N': 1}
>>> json.loads(data['Cart'][1])
{u'PR': 1.2, u'N': u'2'}

Whatever produced this structure first encoded each Cart entry, then encoded the whole structure. Try to avoid this, as decoding now requires two steps.

In Python, you can repair this with:

def do_something(request,pid):
    data = json.loads(request.body)
    data['Cart'] = [json.loads(d) for d in data['Cart']]

but ideally, you should fix the JS code that creates the nested structure.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.