I am totally stumped on this, and must be doing something incredibly stupid. I am trying to simply upload a file on a Django project. The problem seems to be that NO form data is getting passed through to the server--only the csrf token. I am running Django 1.5.1, python 2.7, virtualenv, on a Mac, and using the built-in Django development server.
My HTML form is:
{% load url from future %}
<form enctype="multipart/form-data" method="POST" action="{% url 'showreport' %}">
{% csrf_token %}
<label>Upload grade csv file: </label>
<input type="hidden" id="testing" value="maybe" />
<input type="file" id="grade_csv" />
<input type="submit" value="Generate Report" />
</form>
My model:
from django.db import models
class Document(models.Model):
file = models.FileField(upload_to='/media/', blank=True, null=True)
My forms.py:
from django import forms
from .models import Document
class DocumentForm(forms.Form):
"""
to handle uploading grades csv file
"""
class Meta:
models = Document
My views.py:
def report(request):
"""
Process the CSV file to remove inactive students
Manipulate to get right JSON format
Chart the results
"""
if request.method == 'POST':
form = DocumentForm( request.POST, request.FILES )
if form.is_valid():
newfile = Document( file = request.FILES['file'] )
newfile.save()
classdata = {}
studentdata = {}
return render( request, 'report/showreport.html', { 'classdata': classdata, 'studentdata': studentdata } )
else:
form = UploadFileForm()
return render( request, 'report/index.html', { 'form': form })
I have spent several hours searching for a solution, but nothing seems to work. I have the enctype set correctly (I think), I am using input type 'submit' for the form, and I am binding the form data to my model (doesn't matter, since request.FILES is empty). I also tried using a direct url in my form action (action='/report/showreport/') per this Django newbie page, but that didn't make a difference. As far as I can tell, there are no other scripts binding to the form submit action and overriding the default action.
I also realize that the code above should most likley be request.FILES['grades_csv'] to match the form's input id...yet that also doesn't matter yet, since request.FILES is empty.
In trying to debug, I have set a pdb trace right before the if request.method == "POST" in my view. Using the console, I can see that my request.POST does not include my hidden "testing" input, and that request.FILES is empty. When I run this in a browser, it just returns me to my form page, essentially saying my form is invalid. My pdb results are here:
(Pdb) request.FILES
(Pdb) <MultiValueDict: {}>
(Pdb) request.POST['testing']
(Pdb) *** MultiValueDictKeyError: "Key 'testing' not found in <QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>"
(Pdb) request.POST
<QueryDict: {u'csrfmiddlewaretoken': [u'0tGCChxa3Po619dCi114Sb9jmWRt82aj']}>
If I try to access request.FILES in my views.py without checking if the form is valid, I get this error:
"Key 'file' not found in <MultiValueDict: {}>"
I am stumped and appreciate any help on why I cannot get this to work--it seems like it should be simple. I can manually create and write to files within my project directory using pdb, so I don't think permissions are the problem...the problem is in the form?
Check that you have added enctype
property into form
tag.
Example from official docs:
<form enctype="multipart/form-data" method="post" action="/foo/">
I hope that you have already solved this issue. I had the exactly same issue and I found out I had no name prop in input tag
<input type="file" id="grade_csv" />
that is your input.
if it doesn't have name, django won't take it. So add name prop then it will work well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With