[Django]-Django : CSRF verification failed even after adding {% csrf_token %}

9đź‘Ť

add context_instance=RequestContext(request) to every view that you will use a form inside it:

return render_to_response('index.html', {}, context_instance=RequestContext(request) )


return render_to_response('photos.html', {'photos': photos}, context_instance=RequestContext(request) )
👤Kambiz

5đź‘Ť

Supposing you are using a fairly recent version of Django (1.3/1.4/dev) you should follow these steps :

  • In settings.py, Add the middleware django.middleware.csrf.CsrfViewMiddleware to the
    MIDDLEWARE_CLASSES list.
  • In your template, use the {% crsf_token %} in the form.
  • In your view, ensure that the django.core.context_processors.csrf context processor is used either by :
    • use RequestContext from django.template
    • directly import the csrf processor from from django.core.context_processors

Examples

from django.template import RequestContext
from django.shortcuts import render_to_response

def my_view(request):
    return render_to_response('my_template.html', {}, context_instance=RequestContext(request))

or

from django.core.context_processors import csrf
from django.shortcuts import render_to_response

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

References

(exhaustive post for posterity and future viewers)

👤sberder

3đź‘Ť

A number of things to troubleshoot here:

  • Please load your “index” page in a web browser, do “View Source”, and check if the {% csrf_token %} is being expanded. It should be replaced with an <input> tag. If that’s not happening, then you have problems with your index page. If it is being replaced correctly, then you have problems with your photos page.

  • The POST URL in index.html doesn’t match any of the patterns in urls.py. Your urls.py seems to expect the search term to be part of the URL, but it’s not – you’re sending it as a HTTP POST parameter. You need to access it via request.POST.

👤user9876

2đź‘Ť

Check in the settings, if you have this middleware:

'django.middleware.csrf.CsrfViewMiddleware'

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

👤Goin

1đź‘Ť

You may need to explicitly pass in a RequestContext instance when you use render_to_response in order to get the CSRF values for that template tag.

http://lincolnloop.com/blog/2008/may/10/getting-requestcontext-your-templates/

👤kungphu

0đź‘Ť

Try using the @csrf_protect decorator:

from django.views.decorators.csrf import csrf_protect
from django.shortcuts import render_to_response

@csrf_protect
def photos(request,artist):
    if not artist:
        return render_to_response('photos.html', {'error' : 'no artist supplied'})
    photos = get_photos_for_artist(artist)
    if not photos:
        logging.error('Issue while getting photos for artist')
        return render_to_response('photos.html', {'error': 'no matching artist found'})
    return render_to_response('photos.html', {'photos': photos})  
👤andersem

-1đź‘Ť

This worked for me:

{% csrf_token %}
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.

In views.py:

from django.template import RequestContext

…

…

…

return render_to_response(“home.html”, {}, context_instance=RequestContext(request))

Leave a comment