4

Im sending a POST that creates a new User, and that works.

My question is how do I get back for example the pk of the created user to the ajax response?

         $.ajax({
                url: 'http://localhost:8080/api/v1/create/user/',
                type: 'POST',
                contentType: 'application/json',
                data: '{"uuid": "12345"}',
                dataType: 'json',
                processData: false,
                success: function (r) {
                    console.log(r)
                },
            });

def obj_create(self, bundle, request=None, **kwargs):
        try:
            user = User.objects.create_user(bundle.data['uuid'],'1')
            user.save()


        except:
            pass
        return bundle
Harry
  • 13,091
  • 29
  • 107
  • 167

3 Answers3

8

you can set always_return_data=True within your UserResource's Meta and on POST and PUT request it will return the created object back.

From the docs

always_return_data

Specifies all HTTP methods (except DELETE) should return a serialized form of the data. Default is False.

If False, HttpNoContent (204) is returned on POST/PUT with an empty body & a Location header of where to request the full resource.

If True, HttpAccepted (202) is returned on POST/PUT with a body containing all the data in a serialized form.

Community
  • 1
  • 1
Amyth
  • 32,527
  • 26
  • 93
  • 135
1

Each resource has dehydrate method. You can use it to add any data to response. Here are the docs - http://django-tastypie.readthedocs.org/en/latest/cookbook.html#adding-custom-values

nmb.ten
  • 2,158
  • 1
  • 20
  • 18
1

You could either use the Location header (set by Tastypie by default) or you could try to make Tastypie send the newly created entity back. I believe the first one is simpler. You may also take a look at related SO question: Is it ok by REST to return content after POST?

First you need to slightly modify jQuery XHR objects,

// Required for reading Location header of POST responses.
var _super = $.ajaxSettings.xhr;
$.ajaxSetup({
    xhr: function () {
        var xhr = _super();
        var getAllResponseHeaders = xhr.getAllResponseHeaders;
        xhr.getAllResponseHeaders = function () {
            var allHeaders = getAllResponseHeaders.call(xhr);
            if (allHeaders) {
                return allHeaders;
            }
            allHeaders = "";
            $(["Cache-Control", "Content-Language", "Content-Type", "Expires", "Last-Modified", "Pragma", "Location"]).each(function (i, header_name) {
                if (xhr.getResponseHeader(header_name)) {
                    allHeaders += header_name + ": " + xhr.getResponseHeader(header_name) + "\n";
                }
            });
            return allHeaders;
        };
        return xhr;
    }
});

This is required because (after jQuery $.ajax docs):

At present, due to a bug in Firefox where .getAllResponseHeaders() returns the empty string although .getResponseHeader('Content-Type') returns a non-empty string, automatically decoding JSON CORS responses in Firefox with jQuery is not supported.

A workaround to this is possible by overriding jQuery.ajaxSettings.xhr as follows:

Then you can read the header in the successCallback, like so:

successCallback: errorAwareCall(function (data, t, textStatus, XMLHttpRequest) {
    var loc = XMLHttpRequest.getAllResponseHeaders();
    var pk = parseInt(loc.match(/\/(\d+)(\/)*/)[1]);
    // Do something with the PK
})
Community
  • 1
  • 1
kgr
  • 9,750
  • 2
  • 38
  • 43