Search code examples
djangocsrfdjango-csrf

Django csrf token missing or incorrect error


I have been developing a site using Django and am trying to implement a simple form, based off of one of the models inside my app. I have a few issues with getting it to work, but my current major problem is that I keep receiving the following error: CSRF token missing or incorrect.

I am running Django 1.6 with python 2.7.

I have already looked over the following posts to try fix my problem (and various other solutions to which I give contextual reference to where appropriate), but it has not worked for me:

Django: CSRF token missing or incorrect - Basically, passing RequestContext along with my render_to_response return.

CSRF Token missing or incorrect - I have made sure that django.middleware.csrf.CsrfViewMiddleware appears in my settings.py file and I have tried to add the django.core.context_processors.csrf as instructed to my TEMPLATE_CONTEXT_PROCESSORS setting but there is no change. When I check these settings in the shell, I get the following output:

> from django.conf import settings
> settings.TEMPLATE_CONTEXT_PROCESSORS
('django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug', 'django.core.context_processors.i18n',
'django.core.context_processors.media', 'django.core.context_processors.static',
'django.core.context_processors.tz',
'django.contrib.messages.context_processors.messages')

I placed the following code in my settings.py file but I continue to get the 403 CSRF token error:

import django.conf.global_settings as DEFAULT_SETTINGS

TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.csrf',
)

I have also followed the suggestions given in the error message itself, i.e. makign sure I have the {% csrf_token %} tags in place, using RequestContext instead of Context.

from my views.py file:

from django.shortcuts import render
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from django.template import loader, Context
from django.http import HttpResponse
from forms import StudentForm
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from django.template import RequestContext

def edit(request):
form = StudentForm(request.POST or None)
if form.is_valid():
    form.save()
    return Redirect('/myprofile/')
return render(request, 'myprofile.html',{'form':form})

Please not that I have read several other guides to fixing this problem that involve including RequestContext in several different ways: return render_to_response('myprofile.html', RequestContext(request, {})) and return render_to_response('myprofile.html', RequestContext(request)), none of which worked for me.

my settings.py file:

import django.conf.global_settings as DEFAULT_SETTINGS

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myprofile',
)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
)


TEMPLATE_CONTEXT_PROCESSORS = DEFAULT_SETTINGS.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.csrf',
)

My html code is as follows:

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

  <input type = "submit" name = "Submit" value = "Edit Form">
</form>

Please not that I have also attempted to add the token as a hidden input, but this has not solved my issue. The function that generates this view is also the same function that is referred to by the form's action, <form action = "/myprofile/" ...>.

Any assistance with this issue would be greatly appreciated.


Solution

  • Your problem is here:

    return render_to_response('myprofile.html',{},RequestContext(request))
    

    Although you have added the csrf:

    c = {}
    c.update(csrf(request))
    

    You don't do anything with c. To solve this once and for all, just use the render shortcut:

    from django.shortcuts import render, redirect
    
    def edit(request):
         form = StudentForm(request.POST or None)
         if form.is_valid():
            form.save()
            return redirect('/myprofile/')
         return render(request, 'myprofile.html', {'form': form})
    

    Next, in your template, you only use {% csrf_token %} not both it and {{ csrf_token }}. The tag will render the form field.