josephmisiti
josephmisiti

Reputation: 9974

Django Posts Not Working:

I am using Django 1.2.3 to develop a site. My ajax get requests work fine but the post requests work in development mode (127.0.0.1:8000) but not when I push the site into production using apache + nginx.

Here is an example

urls.py:

(r'api/newdoc/$', 'mysite.documents.views.newdoc'),

views.py

def newdoc(request):
    # only process POST request
    if request.is_ajax():
        data= dict(request.POST)

                # save data to db



    return HttpResponse(simplejson.dumps([True]))

in javascript:

$.post("/api/newdoc/", {data : mydata}, function(data) { alert(data);}, "json");

my alert is never called .... this is a problem because i want to sanitize this data via a django form and the post requests do not seem to making it to the server (in production only).

what am i doing wrong?

UPDATES:

solution: crsf tokens need to be pushed ajax post requests (not gets) as of django 1.3

also, per the link provide below, the following javascript

$.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                // Only send the token to relative URLs i.e. locally.
                xhr.setRequestHeader("X-CSRFToken",
                                     $("#csrfmiddlewaretoken").val());
            }
        }
    });

needs to be changed as follows:

$.ajaxSetup({
        beforeSend: function(xhr, settings) {
            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                // Only send the token to relative URLs i.e. locally.
                xhr.setRequestHeader("X-CSRFToken",
                                     $('input[name="csrfmiddlewaretoken"]').val());
            }
        }
    });

the way the csrf token gets rendered in the form must have changed between 1.25 - 1.3?? regardless, it works. thanks for all your help everyone

Upvotes: 1

Views: 2410

Answers (2)

Thierry Lam
Thierry Lam

Reputation: 46264

Can you directly access your javascript files from the production server? Which Django version are you using in production? If you are using 1.2.5+ in production, you will need to push the csrf token to the server during an AJAX post operation.

See the release notes in 1.2.5 and CSRF

To check your Django version:

import django
django.get_version()

Print the above in your production site or from the shell in your production server while making sure you are using the proper Python path.

Upvotes: 1

Josh Smeaton
Josh Smeaton

Reputation: 48720

Your code appears fine with a cursory glance, but I'll show you an example of my ajax form processing code in a hope it'll help with figuring out the error that's occurring. Though, what @dmitry commented should be your first debugging step - use firebug or the inspector to see if the ajax call returns an error.

// js (jQuery 1.5)
$(form).submit(function(event) {
            event.preventDefault();
            $.post(post_url, $(form).serialize())
              .success(function(data, status, jqxhr) {
                if (data.success) { // form was valid
                    $(form)
                    // other irrelevant code
                    .siblings('span')
                      .removeClass('error')
                      .html('Form Successful');
                } else { // form was invalid
                    $(form).siblings('span').addClass('error').html('Error Occurred');
                }
              })
              .error(function(jqxhr, status, error) { // server error
                $(form).siblings('span').addClass('error').html("Error: " + error);
              });
});


// django
class AjaxFormView(FormView):
    def ajax_response(self, context, success=True):
        html = render_to_string(self.template_name, context)
        response = simplejson.dumps({'success': success, 'html': html})
        return HttpResponse(response, content_type="application/json", mimetype='application/json')


// view deriving from AjaxFormView

    def form_valid(self, form):
        registration = form.save()
        if self.request.is_ajax():
            context = {'competition': registration.competition }
            return self.ajax_response(context, success=True)
        return HttpResponseRedirect(registration.competition.get_absolute_url())

    def form_invalid(self, form):
        if self.request.is_ajax():
            context = { 'errors': 'Error Occurred'}
            return self.ajax_response(context, success=False)
        return render_to_response(self.template_name, {'errors':form.errors})

Actually, comparing the above to your code, you may need to set the content_type in your django view so that jQuery can understand and process the response. Note that the above is using django 1.3 class-based views, but the logic should be familiar regardless. I use context.success to signal if the form processing passed or failed - since a valid response (json) of any kind will signal the jQuery.post that the request was successful.

Upvotes: 1

Related Questions