josedlujan
josedlujan

Reputation: 5600

Django 1.9 CSRF verification failed. Request aborted

I have a problem with CSRF. I know must use: {% csrf_token %} but the problem is the same.

This my form:

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

views.py:

Try 1:

def registro(request):
    return HttpResponse('Hola')

Try 2:

def registro(request):
    c={}
    c.update(csrf(request))
    return render_to_response('registro.html',c)

Try 3:

def registro(request):
    c={}
    return render(request,'nuevavista.html',c)

complete views.py:

from django.shortcuts import render_to_response, HttpResponse, render,RequestContext
from django.core.context_processors import csrf
from django.utils import timezone
from .models import Articulo
from django.template import RequestContext

# Create your views here.


#Nueva vista

def nuevavista(request):
    #return render_to_response(request,'nuevavista.html')
    #return render(request,'blog/nuevavista.html')
    #return HttpResponse('Nueva web')
    return render_to_response(request,'nuevavista.html')
    #return render_to_response('nuevavista.html',context_instance=RequestContext(request)) 

def registro(request):
    #if request.method=='POST':
    c={}
    #c.update(csrf(request))
    #return render_to_response('registro.html',c)
    #return    render(request,'registro.html',context_instance=RequestContext(request))
    #return HttpResponse('Hola')
    return render(request,'nuevavista.html',c)

def home(request):
    articulos = Articulo.objects.all().order_by('-fecha')
    return render_to_response('index.html',{'articulos':articulos})

urls.py:

from django.conf.urls import include,url
from django.contrib import admin
admin.autodiscover()

urlpatterns = [
    #url de nueva vista
    url(r'^nuevavista','blog.views.nuevavista',name="nuevavista"),
    url(r'^registro','blog.views.registro',name="registro"),


    url(r'^admin/', admin.site.urls),
    url(r'^blog/', 'blog.views.home',name='home'),
]

index.html:

<!doctype html>
{% load staticfiles %}
<html lang="en">
<head>
  <meta charset="utf-8">

  <title>Mi pagina</title>

  <!--<link rel="stylesheet" href="css/styles.css?v=1.0">-->
 <link rel="stylesheet" href="{% static 'css/estilo.css' %}" />
</head>
<body>
    <p>Mi primera pagina </p>

    {% for articulo in articulos %}
    <h1> <a href="{% url 'blog.views.nuevavista' %}" >Titulo   {{articulo.titulo}}</a></h1>
    <p>Autor {{articulo.autor}}</p>
    <p>Texto del articulo {{articulo.texto}}</p>
    <p>Fecha {{articulo.fecha}} </p>
    {% endfor %}


    <p>Formulario</p>
    <form action="." method="post">
        {% csrf_token %}
        <!--<input type='hidden' name='csrfmiddlewaretoken' value='randomchars'/>-->
        <label> Nombre: </label>
        <input id="nombre" type="text" maxlength="100">
        <input type="submit" value="envíar">
    </form>


</body>
</html>

registro.html:

<!doctype html>
{% load staticfiles %}
<html lang="en">
<head>
  <meta charset="utf-8">

  <title>Mi pagina</title>

  <!--<link rel="stylesheet" href="css/styles.css?v=1.0">-->
 <link rel="stylesheet" href="{% static 'css/estilo.css' %}" />
</head>
<body>
    <p>Registro </p>    
</body>
</html>

Upvotes: 0

Views: 1020

Answers (1)

Alasdair
Alasdair

Reputation: 308829

For the {% csrf_token %} tag to work, you must ensure that the template is rendered with the request object (see the docs).

The easiest way to do this is to use the render shortcut instead of render_to_response. The render_to_response method is not recommended, and is likely to be removed from Django in future.

from django.shortcuts import render

def registro(request):
    c = {}  
    # put any other context you need in c
    # no need for c.update(csrf(request)) because we're using render    
    return render(request, 'registro.html', c)

You need to update any views that use csrf_token in their templates. In this case, you haven't updated the home view that renders the form in the index.html template.

def home(request):
    articulos = Articulo.objects.all().order_by('-fecha')
    return render(request, 'index.html', {'articulos':articulos})

Upvotes: 2

Related Questions