3

I am trying to use this form to add to a table in the database. I am currently getting the error "CSRF verification failed. Request aborted.," but I was getting others errors with different tweaks to this code. How do I get this code to work and what is the best practice for writing a form like this?

models.py

from django.db import models
from django.contrib.auth.models import User

class Portfolio(models.Model):
    user = models.ForeignKey(User)
    name = models.CharField(max_length=30)
    description = models.CharField(max_length=100)

    def __unicode__(self):
        return self.name

forms.py

from django import forms

class CreatePortfolio(forms.Form):
    name = forms.CharField(max_length=30)
    description = forms.CharField(max_length=100)

views.py

from django.http import HttpResponse
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.core.context_processors import csrf
from portfolio.models import Portfolio
from portfolio.forms import CreatePortfolio

def portfolio(request):
    if request.method == 'POST':
        portfolio_form = CreatePortfolio(request.POST)
        if form.is_valid():
            csrf_token = django.middleware.csrf.get_token(request)
            port_name = form.cleaned_data['name']
            port_description = form.cleaned_data['description']
            port_user = request.user
            new_portfolio = Portfolio(name=port_name, description=port_description, user=port_user)
            new_portfolio.save()
            return render_to_response('portfolio.html', {'csrf_token': csrf_token})
    else:
        portfolio_form = CreatePortfolio()
    return render_to_response('portfolio.html', {'portfolio_form': portfolio_form})

portfolio.html

<form method="post" action="">
    {% csrf_token %}
    <div class="field">
        <label for="id_name">Name:</label>
            {{ portfolio_form.name}}
    </div>
    <div class="field">
        <label for="id_description">Description:</label>
        {{ portfolio_form.description }}
    </div>
    <input type="submit" value="Create">
</form>

2 Answers 2

2

You do not have to explicitly send the csrf_token. Django takes care of it for you.

Every time a form is submitted, it verifies the token, and generates a new token for subsequent requests. Here, you are forcing it to use the same token, hence the error.

Your view should look something like this:

def portfolio(request):
    if request.method == 'POST':
        portfolio_form = CreatePortfolio(request.POST)
        if form.is_valid():
            port_name = form.cleaned_data['name']
            port_description = form.cleaned_data['description']
            port_user = request.user
            new_portfolio = Portfolio(name=port_name, description=port_description, user=port_user)
            new_portfolio.save()
            return render_to_response('portfolio.html', {}, context_instance=RequestContext(request))
    else:
        portfolio_form = CreatePortfolio()
    return render_to_response('portfolio.html', {'portfolio_form': portfolio_form}, context_instance=RequestContext(request))
Sign up to request clarification or add additional context in comments.

Comments

0

The problem is that you aren't adding the csrf token to your context in render_to_response.

Either use RequestContext to render your view (which automatically includes csrf in its context) like so:

from django.template import RequestContext

def portfolio(request):
    # ... view code here
   return render_to_response("portfolio.html", {'portfolio_form': portfolio_form}, context_instance=RequestContext(request))

or update the csrf manually like so:

from django.core.context_processors import csrf
from django.shortcuts import render_to_response

def portfolio(request):
    # ... view code here

    c = {'portfolio_form': portfolio_form}
    c.update(csrf(request))
    return render_to_response("portfolio.html", c)

See here for more references

https://docs.djangoproject.com/en/dev/ref/contrib/csrf/

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.