niklasfi
niklasfi

Reputation: 15921

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': form,
    })

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>

Upvotes: 18

Views: 30090

Answers (7)

gjm
gjm

Reputation: 306

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.

Upvotes: 19

Suraj Jha
Suraj Jha

Reputation: 47

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......

Upvotes: 1

itzMEonTV
itzMEonTV

Reputation: 20339

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,
    })

Upvotes: 1

Steven Keith
Steven Keith

Reputation: 1799

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',
)

Upvotes: 9

user225852
user225852

Reputation:

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',
)

Upvotes: 1

Steve Jalim
Steve Jalim

Reputation: 12195

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

Upvotes: 7

Blue Peppers
Blue Peppers

Reputation: 3808

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.

Upvotes: 2

Related Questions