0

This is a continuation of my previous post where I attempted to submit multiple forms at once, using one submit button. I tried to resolve the issue in the comment section, however I did not succeed.

The code appears to be fine, however, for some reason I get a 403 error (CSRF verification failed. Request aborted). Moreover, this is what I get in the command prompt:

UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext. "A {% csrf_token %} was used in a template, but the context "

Could anyone please assist me in figuring out what the problem is?

Django version 1.9.2

html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title></title>
</head> 
<body>
    <form action="{% url "list" %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.as_p }}
        {{ form2.as_p }}
        <p><input type="submit" value="Upload"/></p>
    </form>  
 </body>  
</html>

views.py

# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse

from myproject.myapp.models import Document
from myproject.myapp.forms import DocumentForm
from myproject.myapp.forms import DocumentForm2
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt,csrf_protect


#@csrf_exempt <-- tried adding this, still doesn't work
def list(request):
    # Handle file upload
    if request.method == 'POST':
        form = DocumentForm(request.POST, prefix="form")
        form2 = DocumentForm2(request.POST, prefix="form2")

        if form.is_valid() or form2.is_valid():        
            newdoc = Document(docfile=request.FILES['docfile'])

            # Redirect to the document list after POST
            return HttpResponseRedirect(reverse('myproject.myapp.views.list'))

    else:

        form = DocumentForm(prefix="form")  
        form2 = DocumentForm2(prefix="form2")  
        #return render_to_response('list.html', {'form': form, 'form2': form2})

    # Load documents for the list page
    documents = Document.objects.all()

    # Render list page with the documents and the form
    return render(request, 'list.html', {'documents': documents, 'form': form, 'form2': form2})

forms.py

# -*- coding: utf-8 -*-   
from django import forms


class DocumentForm(forms.Form):
    docfile = forms.FileField(
        label='Select a file'
        )

class DocumentForm2(forms.Form):
    docfile2 = forms.FileField(
        label='Select a file'
        )

models.py

# -*- coding: utf-8 -*-
from django.db import models


class Document(models.Model):
    docfile = models.FileField(upload_to='documents')

urls.py

# -*- coding: utf-8 -*-
from django.conf.urls import patterns, url

urlpatterns = patterns('myproject.myapp.views',
    url(r'^list/$', 'list', name='list'),
)
Community
  • 1
  • 1
mr_man
  • 91
  • 2
  • 9
  • are you using AngularJS ? – Soufiaane Feb 05 '16 at 21:45
  • using Firefox or chrome developper tools, can you confirm 1) in the POST request header is there an 'X-CSRFToken' field 2) in the coockies is there a coockie named 'csrftoken' ? – Soufiaane Feb 05 '16 at 22:08
  • Is that definitely your current code. The `{% csrf_token %}` tag should work when you use the `render` shortcut, however, I see that you've commented out `render_to_response()` without `RequestContext`, which wouldn't work. Make sure you have restarted the server after changing code, and refreshed the page before filling out and submitting the form. – Alasdair Feb 05 '16 at 22:08
  • @SoufianeMghanen Hmm, there is no X-CSRFToken field in the POST request header. However, there is a cookie named csrftoken. @Alasdair I changed the last line in `views.py` to: `return render_to_response('list.html',{'documents': documents, 'form': form, 'form2': form2}, context_instance=RequestContext(request))`, then restarted the server. But still no luck... – mr_man Feb 05 '16 at 22:33
  • @mr_man the abscence of the X-CSRFToken in the header is what causing you this problem. let me check a few things to see how we could fix this.. – Soufiaane Feb 05 '16 at 22:36
  • What Django version are you using ? can you show us your MIDDLEWARE_CLASSES in settings.py ? – Soufiaane Feb 05 '16 at 22:49
  • @SoufianeMghanen It is version 1.9.2. `MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', )` – mr_man Feb 05 '16 at 22:52
  • No, don't switch to `render_to_response`, it is obsolete, always use `render`. What url are you going to to display the form? Please show your urls.py. – Alasdair Feb 05 '16 at 23:17
  • Ah ok, yes I switched back to `render`. I edited my post with `urls.py`. Please have a look. – mr_man Feb 05 '16 at 23:24

0 Answers0