views:

1566

answers:

4

It seems like a simple question, but I've been looking for a couple of hours.

I'm trying to process incoming JSON/Ajax requests with Django/Python.

request.is_ajax() is True on the request, but I have no idea where the payload is with the JSON data

request.POST.dir contains this

['__class__', '__cmp__', '__contains__', '__copy__', '__deepcopy__', '__delattr__',
 '__delitem__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__',
'__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', 
'__setattr__', '__setitem__', '__str__', '__weakref__', '_assert_mutable', '_encoding', 
'_get_encoding', '_mutable', '_set_encoding', 'appendlist', 'clear', 'copy', 'encoding', 
'fromkeys', 'get', 'getlist', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 
'keys', 'lists', 'pop', 'popitem', 'setdefault', 'setlist', 'setlistdefault', 'update', 
'urlencode', 'values']

There are apparently no keys in request post keys

When I look at the POST in Firebug, there is json data being sent up in the request.

+1  A: 

request.POST is just a dictionary-like object, so just index into it with dict syntax.

Assuming your form field is fred, you could do something like this:

if 'fred' in request.POST:
    mydata = request.POST['fred']

Alternately, use a form object to deal with the POST data.

Michael van der Westhuizen
I was looking in request.POST['json'] which contained nothing. len was 0
ראובן
Then it would definitely help to see your JavaScript call, as Daniel suggested.
Vinay Sajip
+2  A: 

the HTTP POST payload is just a flat bunch of bytes. Django (like most frameworks) decodes it into a dictionary from either urlencoded parameters, or mime-multipart encoding. if you just dump the JSON data in the POST content, Django won't decode it. either do the JSON decoding from the full POST content (not the dictionary); or put the JSON data into a mime-multipart wrapper.

in short, show the JavaScript code, the problem seems to be there.

Javier
I see the problem now! The type='json' parameter in jquery refers to what type to expect, not what it sends. It's sending regular form post encoded data, so if I want to send "json" I need to somehow convert it into a string, and pass "json={foo:bar, }" etcI can't believe, however, that that's how most people do it. I must be missing something here.
ראובן
Actually you can convert the form to a JSON string in jQuery with the .serialize() function. But why do you particularly need to send json, though? What's wrong with just sending the form data?
Daniel Roseman
There are many cases where raw form data isn't enough; JSON allows you to send hierarchical objects, not just key : value pairs. You can send nested sets, arrays, etc. You could probably do all of that with post data, but it's not as convenient. It's kinda nice to just always deal with JSON, both to and from
Taxilian
+4  A: 

If you are posting JSON to Django, I think what you want is request.raw_post_data, this will give you the raw JSON data sent via the post, from there you can process it further.

Here is an example using Javascript/jQuery/jquery-json and Django.

Javascript:

var myEvent = {id: calEvent.id, start: calEvent.start, end: calEvent.end,
                allDay: calEvent.allDay };

$.ajax({
        url: '/event/save-json/',
        type: 'POST',
        contentType: 'application/json; charset=utf-8',
        data: $.toJSON(myEvent),
        dataType: 'text',
        success: function(result) {
            alert(result.Result);
        }
    });

Django:

def save_events_json(request):
if request.is_ajax():
        if request.method == 'POST':
            print 'Raw Data: "%s"' % request.raw_post_data  

    return HttpResponse("OK")
aurealus
+2  A: 

I had the same problem - i've been posting a complex JSON response and I couldn't read my data using the request.POST dictionary.

My JSON POST data was:

//JS code:
//requires json2.js & jquery
var response = {data:[{"a":1, "b":2},{"a":2, "b":2}]}
json_response = JSON.stringify(response); //proper serialization method, read http://bit.ly/MjfiJ
$.post('url',json_response);

In this case you need to use method provided by aurealus. Read the request.raw_post_data and deserialize it with simplejson.

#Django code:
from django.utils import simplejson
def save_data(request):
  if request.method == 'POST':
    json_data = simplejson.loads(request.raw_post_data)
    try:
      data = json_data['data']
    except KeyError:
      HttpResponseServerError("Malformed data!")
    HttpResponse("Got json data")
stricjux