Search code examples
djangocsrf

CSRF token missing or incorrect explanation


i am just a beginner and starting with some tutorials on web, i can not understand why this isn't working for me:

my views.py

from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from django.core.context_processors import csrf


class MainPage(View):
    def get(self, request):
        return render_to_response("helloworld.html")


class TestHandler(View):
    def post(self, request):
        q = {}
        q.update(csrf(request))
        #return render_to_response('test.html', q)
        return render_to_response('test.html', {'q':q}, context_instance=RequestContext(self.request))

    def get(self, request):
        q = self.request.GET.get('q')
    return HttpResponse(q) 

and my urls.py

from django.conf.urls import patterns, include, url

from django.contrib import admin
from views import MainPage, TestHandler

admin.autodiscover()

urlpatterns = patterns('',
    # Examples:
     url(r'^hello$', MainPage.as_view(), name='home'),
     url(r'^testform/', TestHandler.as_view()),

    url(r'^admin/', include(admin.site.urls)),

helloworld.html

>->-<html>
>->->-<head>
>->->->-<title>Hello, World!</title>
>->->-</head>
>->->-<body>
>->->->-<form method="post"  action="/testform/" >                                                                                                           
    {% csrf_token %}
>->->-<input name="q">
    <input type="submit">
</form>
>->->-</body>
>->-</html>

test.html

>-<body>
>-Hello {{q}}
>-</body>

This is running on django 1.6, I read most of post and still can't figure it out.


Solution

  • Unfortunately what you have pasted is a bit of a mess, you are using Class Based Views but yet you have mixed them with function based views (also half of the declarations are missing).

    Enable the CSRF Middlware in your settings.py

    MIDDLEWARE_CLASSES = (
        ...
        'django.middleware.csrf.CsrfViewMiddleware',
        ...
    )
    

    Fix your views to proper Class Based Views, what you have pasted is totally wrong:

    from django.views.generic import CreateView, TemplateView
    from django.core.urlresolvers import reverse_lazy
    
    
    # Create the form in your forms.py
    from .forms import (
        MyTestForm,
    )
    
    class MainPage(TemplateView):
        template_name = "test.html"
    
    class TestHandler(CreateView):
        form_class = MyTestForm
        template_name = "helloworld.html"
        success_url = reverse_lazy('home')
    

    Create your form template:

    <html>
        <head>
            <title>Hello, World!</title>
        </head>
        <body>
            <form method="post"  action="/testform/">
                {% csrf_token %}
                <input name="q">
                <input type="submit">
            </form>
        </body>
    </html>