2010-07-07 21 views
14

Deseo realizar un inicio de sesión para mi sitio. Básicamente copié y pegué los siguientes bits del libro de Django juntos. Sin embargo, sigo recibiendo un error (error en la verificación de CSRF. Solicitud cancelada) al enviar mi formulario de registro. ¿Alguien puede decirme qué provocó este error y cómo solucionarlo?csrf error en django

Aquí está mi código:

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> 

Respuesta

17

Estaba teniendo exactamente el mismo problema, y ​​la respuesta de Blue Peppers me puso en el camino correcto. Agregar un RequestContext a su vista de formulario soluciona el problema.

from django.template import RequestContext 

y:

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

que esto esté arreglado para mí.

+1

Con django actual, la mejor solución sería usar render() en lugar de render_to_response(). –

1

es necesario agregar csrf(request) a su contexto.

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) 

Es posible que necesita para convertir su contexto en un objeto Context para esto, no es un dict, pero el principio es el sonido.

5

Suponiendo que usted está en Django 1.2.x, sólo tiene que añadir esto antes {{form.as_p}}:

{% csrf_token %}

Y para entender por qué, disfrutar de los CSRF docs

+0

haciendo eso no era suficiente para mí; se requirió la solución user433033 – Foon

1

Añadir estos 2 middleware en el fichero de configuración si no desea agregar {% csrf_token %} a cada formulario.

MIDDLEWARE_CLASSES = (
    #... 
    'django.middleware.csrf.CsrfViewMiddleware', 
    'django.middleware.csrf.CsrfResponseMiddleware', 
) 
+0

Lo anterior funcionará para Django 1.1 pero no 1.2 –

+1

@stevejalim irónicamente, [docs] (http://docs.djangoproject.com/en/1.2/ref/contrib/csrf/#legacy-method) sugieren todavía funcionaría para 1.2, pero está en desuso. –

+0

¡Ah, tienes razón! –

8

estoy usando Django 1.2.3, tuve algunos problemas intermitentes:

Qué hacer:

Asegúrese de que el token CSRF está presente en su plantilla:

<form action="" method="post">{% csrf_token %} 

Use a RequestContext:

return render_to_response('search-results.html', {'results' : results}, context_instance=RequestContext(request)) 

Asegúrese de utilizar un RequestContext para GET también, si son manejados por la misma función de vista, y renderice la misma plantilla.

es decir:

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)) 
no

:

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

Asegurar 'Django.middleware.csrf.CsrfViewMiddleware' aparece en su 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', 
) 
1

respuesta más tarde.

Ahora render puede utilizar en lugar de context_instance=RequestContext(request)

from django.shortcuts import render 
return render(request, "registration/register.html", { 
     'form': form, 
    }) 
Cuestiones relacionadas