I am using Daxice library to create AJAX calls in my Django app.
When I create a POST
method on a form I get the mentioned error:
Forbidden (403)
CSRF verification failed. Request aborted.
My settings.py have:
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
'django.core.context_processors.request',
'django.contrib.messages.context_processors.messages',
'django.core.context_processors.csrf',
)
My urls.py
from django.conf.urls import patterns, include, url
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from dajaxice.core import dajaxice_autodiscover, dajaxice_config
dajaxice_autodiscover()
urlpatterns = patterns('',
url(dajaxice_config.dajaxice_url, include('dajaxice.urls')),
url(r'^$', 'apps.views.home'),
)
urlpatterns += staticfiles_urlpatterns()
My views.py:
from django.http import HttpResponse
from django.template import loader, Context
from django.core.context_processors import csrf
def home(request):
t = loader.get_template('index.html')
html = t.render(Context( ))
return HttpResponse(html)
My template index.html:
{% load dajaxice_templatetags %}
<html>
<head>
<title>My base template</title>
<script src="http://code.jquery.com/jquery-latest.min.js"
type="text/javascript"></script>
{% dajaxice_js_import %}
<script type="text/javascript">
function shout(data){
alert(data.message)
}
</script>
</head>
<body>
<form method="POST" action="">{% csrf_token %}
Page: <input type="text" name="page"><br>
From: <input type="text" name="from"> (From < To) <br>
To: <input type="text" name="to"> (returns results before that day)<br>
<input type="submit" onclick="Dajaxice.apps.hello(shout);" value="Submit">
</form>
<br>
<br>
<input type="button" onclick="Dajaxice.apps.hello(shout);" value="Get message from server!">
</body>
</html>
And my ajax.py:
import simplejson
from dajaxice.decorators import dajaxice_register
@dajaxice_register(method='GET')
@dajaxice_register(method='POST', name='other_post')
def hello(request):
return simplejson.dumps({'message':'Hello from Python!'})
If I click the button, the message gets alerted. When I submit the form I get this error. How can I fix it?
Finally I believe I have fixed all the possibilities for the CSRF display in the debug page:
In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django's CSRF mechanism has not been used correctly. For POST forms, you need to ensure:
Your browser is accepting cookies.
The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.
Alright I think I got it. In the line:
<form>
...
<input type="submit" onclick="Dajaxice.apps.hello(shout);" value="Submit"></form>
...
</form>
If the type
is button
it works. It should be something with the submit
behavior of the server request. I'm not an expert to explain why is this happening, so if somebody can explain I would gladly give the vote.