How to create POST Form in Django 1.3 without CSRF problem


Creating form with POST, doing validation and process the input is easy in Django 1.3. But, seems a lot of people facing this CSRF problem :

Forbidden (403)
CSRF verification failed. Request aborted.
Reason given for failure:
CSRF token missing or incorrect.

In general, this can occur when there is a genuine Cross Site Request Forgery, or when Django’s CSRF mechanism has not been used correctly. For POST forms, you need to ensure:

The view function uses RequestContext for the template, instead of Context.
In the template, there is a {% csrf_token %} template tag inside each POST form that targets an internal URL.
If you are not using CsrfViewMiddleware, then you must use csrf_protect on any views that use the csrf_token template tag, as well as those that accept the POST data.

You’re seeing the help section of this page because you have DEBUG = True in your Django settings file. Change that to False, and only the initial error message will be displayed.

You can customize this page using the CSRF_FAILURE_VIEW setting.


If you go to Django documentation, seems it very un-clear how to add csrf_token in Django 1.3. So here are how to build post form with csrf token in Django 1.3. I will use example here.

models.py

1
2
3
4
5
6
7
from django.db import models

# Create your models here.
class Post(models.Model):
    name = models.CharField(max_length=255)
    content = models.TextField()
    created = models.DateField()

views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from django.shortcuts import render
from posts.forms import PostsForms

def index(request):
    form = PostsForms()
   
    if request.method == ‘POST’:
        form = PostsForms(request.POST)
        if form.is_valid():
            return render(request, ‘posts/index/html’, {‘value’: ‘okay’})
    else:
        form = PostsForms() # unbound form
       
    return render(request, ‘posts/index.html’, {‘form’: form})

forms.py

1
2
3
4
5
6
from django import forms

class PostsForms(forms.Form):
    name = forms.CharField(required=True)
    content = forms.CharField(required=True)
    created = forms.DateField(required=True)

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{% block content %}{% csrf_token %}
    {% if value %}
        {{ value }}
    {% else %}
   
        {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}       
        <form action="" method="post">
            {% csrf_token %}
            {{ form.as_p }}
            <input type="submit" value="Submit" />
        </form>
   
    {% endif %}
   
{% endblock %}

settings.py

1
2
3
4
5
6
7
MIDDLEWARE_CLASSES = (
    ‘django.middleware.common.CommonMiddleware’,
    ‘django.contrib.sessions.middleware.SessionMiddleware’,
    ‘django.middleware.csrf.CsrfViewMiddleware’,
    ‘django.contrib.auth.middleware.AuthenticationMiddleware’,
    ‘django.contrib.messages.middleware.MessageMiddleware’,
)

For settings.py, I use default configuration. But make sure you have same as mine.

Then run your server and test the form. You should not see “avoid CSRF token missing or incorrec” anymore :).


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.