views:

125

answers:

4

Hello,

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>
A: 

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.

Blue Peppers
+3  A: 

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

stevejalim
A: 

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',
)
Laurent De Marez
The above will work for Django 1.1 but not 1.2
stevejalim
@stevejalim ironically, [docs](http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#legacy-method) suggest it would still work for 1.2 but it's deprecated.
rebus
Ah you're right!
stevejalim
A: 

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.