0

I'm trying to write a webpage that allows user to input an "Idea" and save it to the database. I want to use the Post method of the form. I tried following the instructions on the django page, but the authentication still fails.

This is my form code:

<form action="/" method="post">
   {% csrf_token %} 
   <p> Title: </p>  <input type="text" name="title"> </br>  
   <p> Details: </p> <input type="text" name="details"> 
   <input type="submit" value="Post"> 
</form>

My URLconf redirects / to Ideas.views.home with the line

url(r'^$', 'Ideas.views.home' , name='home')

The view itself is

from django.shortcuts import render, render_to_response
from django.http import HttpResponse
from django.template import loader, Template, Context, RequestContext   
from django.core.context_processors import csrf 
from Ideas.models import Idea 


# Create your views here.
def home(request):
    if request.method == 'POST': 
        submitted = Idea.objects.create(title=request.POST['title'], detail=request.POST['details'], votes=0) 
        submitted.save()
    m = RequestContext(request, {"passed_ideas": Idea.objects.all()})
    return render_to_response('basic.html', m)  

I have also tried doing this:

from django.shortcuts import render, render_to_response
from django.http import HttpResponse
from django.template import loader, Template, Context, RequestContext   
from django.core.context_processors import csrf 
from Ideas.models import Idea 


# Create your views here.
def home(request):
    c = {} 
    c.update(csrf(request)) 
    if request.method == 'POST': 
        submitted = Idea.objects.create(title=request.POST['title'], detail=request.POST['details'], votes=0) 
        submitted.save()
    c['passed_ideas'] = Idea.objects.all()
    return render_to_response('basic.html', c)  

How do I get the CSRF authentication to work?

elder4222
  • 355
  • 2
  • 15

4 Answers4

0

I had a similar problem a few weeks back. It seems that redirecting to the url with '/' causes it to drop the CSRF token. If that is the problem, add trailing_slash=False to your router:

# urls.py
router = DefaultRouter(trailing_slash=False)

urlpatterns = patterns('', 
    url(r'^$', views.IndexView.as_view(), name='home'),
    #all of your urls go here
)

This will eliminate the redirect, and the CSRF token should come through.

Chris Belyeu
  • 208
  • 1
  • 9
0

I think you need to add context_instance=RequestContext(request) when you render your template in order to process your csrf token

 return render_to_response('basic.html', c, context_instance=RequestContext(request))  
klasske
  • 2,164
  • 1
  • 24
  • 31
0

Thanks everyone who helped, but switching from

return render_to_response(...) 

to

return render(request, ...) 

finally fixed it

elder4222
  • 355
  • 2
  • 15
  • after this, I found a similar (although not the exact same) post here: http://stackoverflow.com/questions/10388033/csrf-verification-failed-request-aborted?rq=1 – elder4222 Aug 27 '14 at 19:17
0

Yes, you have to use render, or you have to add crsf to the render to response like so:

render_to_response('basic.html', add_csrf(request, ***other context***))


from django.core.context_processors import csrf
def add_csrf(request, ** kwargs):
   """Add CSRF and user to dictionary."""
   d = dict(user=request.user, ** kwargs)
   d.update(csrf(request))
   return d

Not that I like this option, but this is how I did it. I think the RequestContext is a better option.

gabn88
  • 781
  • 8
  • 23