How to send data as key - value pairs instead of string via POST using XHR

I'm creating two POST calls. One using a django form and one using angular js via a resource xhr.

The angular setup looks like this:

myModule.factory('gridData', function($resource) {
    //define resource class
    var root = {{ root.pk }};
    var csrf = '{{ csrf_token }}';
    return $resource('{% url getJSON4SlickGrid root.pk %}:wpID/', {wpID:'@id'},{
            get: {method:'GET', params:{}, isArray:true},
            update:{method:'POST', headers: {'X-CSRFToken' : csrf }}
    });
});

With creating an xhr post request as such:

item.$update();

This post request is send to the server as expected, but when I want to access the QueryDict I cannot access the data passed using:

name = request.POST.get('name', None)

name is always None like this.

The issue behind this is that the QueryDict object is getting parsed quite strange.

 print request.POST
<QueryDict: {u'{"name":"name update","schedule":0"}':[u'']}>

Whereas I would have expected this result, which I got when I send the data via a "normal" Post request:

<QueryDict: {u'name': [u'name update'], u'schedule': [u'0']}>

So it seems to be that Django receives something in the POST request which instructs Django to parse the parameters into one string. Any idea how to circumvent this?

Update:

I found this discussion where they say that the issue is if you provide any content type other than MULTIPART_CONTENT the parameters will be parsed into one string. I checked the content-type send with the POST request and it is really set to 'CONTENT_TYPE': 'application/json;charset=UTF-8'. Thus this is likely the issue. Therefore my question is: How can I set the CONTENT_TYPE for a xhr post request created using angular.js resources to MULTIPART_CONTENT?

you could either:

  • fiddle with the client to send data instead of json
  • use json.loads(request.raw_post_data).get('name', None) (django < 1.4)
  • use json.loads(request.body).get('name', None) (django >= 1.4)

The Angular documentation talks about transforming requests and responses

To override these transformation locally, specify transform functions as transformRequest and/or transformResponse properties of the config object. To globally override the default transforms, override the $httpProvider.defaults.transformRequest and $httpProvider.defaults.transformResponse properties of the $httpProvider.

you can find an example here as was previously pointed at.