csrf error in django

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.


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


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

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.