25

Beginner at Django here, I've been trying to fix this for a long time now. I do have 'django.middleware.csrf.CsrfViewMiddleware' in my middleware classes and I do have the token in my post form.

Heres my code, what am I doing wrong?

from django.contrib.auth.forms import UserCreationForm
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from chartsey.authentication.forms import RegistrationForm
from django.template import RequestContext
from django.core.context_processors import csrf

def register(request):

    if request.method == 'POST':
        c = RequestContext(request.POST, {})
        form = RegistrationForm(c)
        if form.is_valid():
            new_user = form.save()
            return HttpResponseRedirect("/")
    else:
        form = RegistrationForm()

    return render_to_response("register.html",  {'form': form,  }, )

Here's my Template:

{% block content %}

    <h1>Register</h1>
    <form action="" method="POST"> {% csrf_token %}
        {{ form.as_p }}
    <input type="submit" value="Submit">
    </form>

{% endblock %}
aroooo
  • 4,726
  • 8
  • 47
  • 81

10 Answers10

30

Update: This answer is from 2011. CSRF is easy today.

These days you should be using the render shortcut function return render(request, 'template.html') which uses RequestContext automatically so the advice below is outdated by 8 years.

  1. Use render https://docs.djangoproject.com/en/2.2/topics/http/shortcuts/
  2. Add CSRF middleware https://docs.djangoproject.com/en/2.2/ref/csrf/
  3. Use the {% csrf_token %} template tag
  4. Confirm you see the CSRF token value being generated, AND submitted in your form request

Original Response

My guess is that you have the tag in the template but it's not rendering anything (or did you mean you confirmed in the actual HTML that a CSRF token is being generated?)

Either use RequestContext instead of a dictionary

render_to_response("foo.html", RequestContext(request, {}))

Or make sure you have django.core.context_processors.csrf in your CONTEXT_PROCESSORS setting.

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Or add the token to your context manually

Community
  • 1
  • 1
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • That did it! I'm still having a little trouble fully understanding it, but at least I'm past staring blankly and trying to randomly change things. The docs didn't help me too much, thanks so much! – aroooo Nov 11 '11 at 04:32
  • This is step 3 in the docs :) Django's docs are amazing if you let yourself dig in a little bit. Good luck! – Yuji 'Tomita' Tomita Nov 11 '11 at 09:36
  • Thank you very much, this solved my problem. General advice for everyone: check if you user render_to_response() with the proper parameters, I messed up and given it 3 parameters, therefore it resulted in the above error. – Phonebox Jul 07 '15 at 14:37
6

Just add this to your views

return render_to_response("register.html", {'form': form, }, context_instance = RequestContext(request))

It will work!!

TRR
  • 1,637
  • 2
  • 26
  • 43
Njogu Mbau
  • 446
  • 1
  • 7
  • 14
4

Try using render instead of render_to_response:

from django.shortcuts import render

render(request, "foo.html", {})

Django - what is the difference between render(), render_to_response() and direct_to_template()?

As stated in the link above it was introduced in Django 1.3 and automatically uses RequestContext

Community
  • 1
  • 1
Kamen Tsvetkov
  • 519
  • 5
  • 9
1

for Django version 3.0 add the below annotation

@csrf_protect
def yourfunc(request):
    return render(request, '../your.html', None)

And don't forget add the below tag in your field

<form action="add/" method="post">
  {% csrf_token %}
...
</form>
ImDroidGuy
  • 11
  • 1
0

If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.

Neeraj Sharma
  • 1,322
  • 10
  • 9
0

The addition of RequestContext is the key when using render_to_response as mentioned by @Yuji 'Tomita' Tomita and @Njogu Mbau. However, what initially threw me off when I was struggling with this problem was that I had to add RequestContext to both the function in views.py that initially loads the template and to the function in views.py that handles the submission from the template.

Also, just for reference, here are some other links that discuss this same problem

Community
  • 1
  • 1
wingr
  • 2,460
  • 24
  • 12
0

Also got this error randomly on some pages after I installed django-livereload-server. Uninstalling django-livereload-server did the trick.

lukeaus
  • 11,465
  • 7
  • 50
  • 60
0

I had this issue too, but honestly, I hit refresh on my browser a few minutes later without changing anything and it worked that time. I had this message in my command line as so it might provide a clue as to what was causing the issue:

Not Found: /css/reset/reset.css
[03/Jul/2020 20:52:13] "GET /css/reset/reset.css HTTP/......
cheznead
  • 2,589
  • 7
  • 29
  • 50
0

DJANGO/AJAX WORKFLOW FULL METHOD IS HERE :)

const url = "{% url 'YOUR_URL_NAME' pk=12345 %}".replace(/12345/, id.toString());
$.ajax({
        type: 'POST',
        url: url,
        data: {'id':id, "csrfmiddlewaretoken": '{{csrf_token}}'},
        beforeSend: function() { $('#response').text('Please wait ...'); },
        success: function (response) {
            console.log(response)           
        },
        error: function (response) {
            console.log(response)
        }
    })

Hope It Will Work !!!

Sanjay Sikdar
  • 435
  • 4
  • 10
-1

What worked for me was commenting out the below line from my settings.py

'django.middleware.csrf.CsrfViewMiddleware'