1

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.

Community
  • 1
  • 1
PyUnchained
  • 560
  • 1
  • 7
  • 16

2 Answers2

4

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.

Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • 1
    Thanks for the help. I've followed your suggestions but am still receiving the same error. This leads me to believe that this issue might be arising from a different aspect of my code, rather than just the raw code inside the files. – PyUnchained Jul 21 '14 at 20:47
2

{{ csrf_token }} seems to be empty and overrides the hidden input field which is generated by {% csrf_token %}. just remove the hidden input field with {{ csrf_token }} from your template and it should work probably.

Also, as you are using RequestContext you don't have to add the CSRF token manually to the template, so you can remove following code from your view.

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

See https://docs.djangoproject.com/en/1.6/ref/contrib/csrf/#how-csrf-works for more information.

  • Thanks for the response. I commented on Khalid's answer, only because his covered the same idea and more. Your link did provide me with some very useful added information I had missed, but hasn't quite solved my issue. – PyUnchained Jul 21 '14 at 21:10