csrf error in django
I want to realize a login for my site. I basically copied and pasted the following bits from the Django Book together. However I still get an error (CSRF verification failed. Request aborted.), when submitting my registration form. Can somebody tell my what raised this error and how to fix it?
Here is my code:
views.py:
# Create your views here.
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/books/")
else:
form = UserCreationForm()
return render_to_response("registration/register.html", {
'form': for开发者_如何学Gom,
})
register.html:
<html>
<body>
{% block title %}Create an account{% endblock %}
{% block content %}
<h1>Create an account</h1>
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Create the account">
</form>
{% endblock %}
</body>
</html>
I was having the exact same issue - and Blue Peppers' answer got me on the right track. Adding a RequestContext to your form view fixes the problem.
from django.template import RequestContext
and:
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/books/")
else:
form = UserCreationForm()
c = {'form': form}
return render_to_response("registration/register.html", c, context_instance=RequestContext(request))
This fixed it for me.
I'm using Django 1.2.3, I had a few intermittent problems:
Things to do:
Ensure the csrf token is present in your template:
<form action="" method="post">{% csrf_token %}
Use a RequestContext:
return render_to_response('search-results.html', {'results' : results}, context_instance=RequestContext(request) )
Make sure you use a RequestContext for GETs as well, if they are handled by the same view function, and render the same template.
i.e:
if request.method == 'GET':
...
return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request) )
elif request.method == 'POST':
...
return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request))
not:
if request.method == 'GET':
...
return render_to_response('search-results.html', {'results':results})
elif request.method == 'POST':
...
return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request))
Ensure 'django.middleware.csrf.CsrfViewMiddleware' is listed in your settings.py
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',
)
Assuming you're on Django 1.2.x, just add this before {{form.as_p}}
:
{% csrf_token %}
And to understand WHY, check out the CSRF docs
You need to add csrf(request)
to your context.
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.context_processors import csrf
def register(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
new_user = form.save()
return HttpResponseRedirect("/books/")
else:
form = UserCreationForm()
con = {'form': form}
con.update(csrf(request))
return render_to_response("registration/register.html", con)
You might need to turn your context into a Context
object for this, not a dict
, but the principle is sound.
Add these 2 middlewares to the settings file if you don't want to add {% csrf_token %}
to each form.
MIDDLEWARE_CLASSES = (
#...
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.csrf.CsrfResponseMiddleware',
)
Later answer.
Now render
can use instead of context_instance=RequestContext(request)
from django.shortcuts import render
return render(request, "registration/register.html", {
'form': form,
})
Try removing the following line from your settings.py's MIDDLEWARE list if you intend to use the {% csrf_token %}:
'django.middleware.csrf.CsrfViewMiddleware',
Worked for me......
精彩评论