0

I need to post form data to a Django view before the form is submitted. All methods I try fail on the same point. The javascript to make the ajax call is:

$('#lockdown-email-form input[type=text]').focusout(function() {
    var data = $('#lockdown-email-form form').serialize()    
    $.post("/lockdown-email", data)
})

and the python that receives the call is:

def lockdown_email(request):
    msg = ''
    logger.info(request.method)
    if request.method == 'POST':
        form = LockdownEmailForm(request.POST)
        if form.is_valid():
            email_content = "Email:\n" + form.cleaned_data['email']
            mail_admins('Email for preview submission', email_content)
            msg = 'Thank you! Entering site.'
        else:
            msg = 'Email required'
    return HttpResponse(msg)

Problem is is that every time the request is made there's a redirect to the same URL but with GET method (from looking in dev tools network tab), so the function doesn't work. I've searched for a long time; some advice relates to CSRF but I've disabled this in settings.py and it still doesn't work.

This is on the django-lockdown page, although this specific example doesn't interact with lockdown. Any ideas?

EDIT:

urls.py

from django.conf.urls import patterns, url
from django.views.generic import TemplateView

from app import views

urlpatterns = patterns('',
    url(r'^robots.txt$', TemplateView.as_view(template_name="app/robots.txt")),
    url(r'^$', views.index, name='index'),
    url(r'lockdown-email$', views.lockdown_email, name='lockdown_email'),
    url(r'get-locations$', views.get_locations, name='get_locations'),
    url(r'amend-data$', views.amend_data, name='amend_data'),
    url(r'feedback$', views.feedback, name='feedback'),
    url(r'contest-data$', views.contest_data, name='contest_data'),
)
Collierre
  • 946
  • 8
  • 16
  • can you post your `urls.py`? Does the URL need to be `/lockdown-email/`? If Django is creating a redirect it sounds like it could be an issue with the routing in `urls.py`. – Henry Florence Nov 05 '13 at 19:52
  • Done, thanks for the input. I'd be surprised if it was this as all my other forms work ok with the same kind of patterns. – Collierre Nov 05 '13 at 20:11
  • I doubt this will solve your problem, but shouldn't your urls have a ^ at the start, e.g. `url(r'^lockdown-email$'`? Right now they're matching too broadly. – Greg Nov 05 '13 at 20:21
  • Seems that's the better way to do it, thanks. But no didn't change anything. – Collierre Nov 05 '13 at 20:22
  • I'm wondering if it's anything to do with django-lockdown stopping the request. I just made the following change in settings.py though and no change: `LOCKDOWN_URL_EXCEPTIONS = (r'^/admin.*$', r'^lockdown-email$')` – Collierre Nov 05 '13 at 20:24
  • Does the view for the page that sends the Ajax request receive a new `LockdownEmailForm`? – Henry Florence Nov 05 '13 at 20:28
  • Right it seems like it is to do with django-lockdown, as I put the form on a normal page and it worked ok. – Collierre Nov 05 '13 at 20:36
  • @HenryFlorence the view is the automatic lockdown one; I'm not sure. More weirdness, now if I focusout (see js) twice, on the second time it works. – Collierre Nov 05 '13 at 20:55

1 Answers1

0

Well I have a temporary, and pretty unsatisfactory solution.

For some reason which I don't yet understand (but most likely to do with django-lockdown) the first time the ajax POST request is made it redirects to a GET, but the second time it behaves as expected. So my solution is simply to change my js to look like this:

$('#lockdown-email-form input[type=text]').focusout(function() {
    var data = "email=" + $('#lockdown-email-form input[type=text]').val()

    $.ajax({
        url: '/lockdown-email',
        type: 'POST',
        async: false,
        data: data,
    })
    $.ajax({
        url: '/lockdown-email',
        type: 'POST',
        async: false,
        data: data,
    })

})

Using ajax not post to ensure synchrous requests. I'll be looking for a better solution though.

Collierre
  • 946
  • 8
  • 16