1

Hello I hava a problem with Django, I have a this error:

CSRF token missing or incorrect.

and my code is:

 <h1>Registro de llamadas</h1>


    <form action="{% url 'registro:guardar' %}" method="post">
    {% csrf_token %}
    Duracion: <input type="text" name="duracion"  /> </br>
    Tipo de llamada: 
    <select name="tipo" form="carform">
      <option value="1">Local</option>
      <option value="2">Nacional</option>
      <option value="3">Internacional</option>
    </select>
</br>
<input type="submit" value="Grabar" />
</form>

{% if llamadas %}
    <ul>
    {% for ll in llamadas %}
        <li><a href="a">{{ ll.duracion }}</a></li>
    {% endfor %}
    </ul>
{% else %}
    <p>No tenemos ninguna llamada</p>
{% endif %}

and views.py I have:

from django.http import HttpResponse
from django.template import loader


def index(request):
    template = loader.get_template('registro/index.html')
    return HttpResponse(template.render(request))


def guardar(request):
    template = loader.get_template('registro/index.html')
    return HttpResponse(template.render(request))

Please some help, I searched other question but not solve my problem.

THanks!

3 Answers3

2

For the CSRF token to work properly you need to include a RequestContext when you use your template.

To avoid the extra boilerplate this involves django comes with a shortcut function which adds this for you automatically when rendering a template. This is django.shortcuts.render.

To use this change your view to be.

from django.shortcuts import render

def guardar(request):
    return render(request, 'registro/index.html', {})

For more information this page of the Django docs is very useful.

Simon Gibbons
  • 6,969
  • 1
  • 21
  • 34
1

The problem is that request is the second argument to the template.render() method, but you are passing it as the first.

You can fix your views as follows:

def index(request):
    template = loader.get_template('registro/index.html')
    return HttpResponse(template.render(request=request))

def guardar(request):
    template = loader.get_template('registro/index.html')
    return HttpResponse(template.render(request=request))

As Simon suggests in his answer, it is easier to use the render shortcut instead of manually loading and rendering the template.

from django.shortcuts import render

def index(request):
    return render(request, 'registro/index.html', {})

def guardar(request):
    return render(request, 'registro/index.html', {})
Alasdair
  • 298,606
  • 55
  • 578
  • 516
0

change your view.py:

from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render

@csrf_exempt
def guardar(request,username=None, errmsg=None):
    template = 'registro/index.html'
    ctx = {}
    render(request, template, ctx)
Oztro
  • 86
  • 1
  • 12