I'm sorry to ask a simple question that has been asked and answered on this site before, but I am starting to learn Django and I haven't been able to resolve my problem by referring to those earlier questions or the docs. I have a simple app that lets users upload .txt files, and that works. I now want to add to the app so as to perform a trivial function on the uploaded text files, but I keep getting MultiValueDictKeyError on the line that tries to implement the function. Here is the function I am trying to implement (this is sample_functions.py):
def print_file_contents(file_object):
with open(file_object) as f:
f = f.decode("utf-8")
f = f.read()
print f
Here is my models.py:
from django.db import models
from django.forms import ModelForm
class Upload(models.Model):
pic = models.FileField("Choose a text file to upload", upload_to="text/")
upload_date=models.DateTimeField(auto_now_add =True)
# FileUpload form class.
class UploadForm(ModelForm):
class Meta:
model = Upload
Here is my views.py:
from django.shortcuts import render
from uploader.models import UploadForm,Upload
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from uploader.resources.sample_functions import print_file_contents
# Create your views here.
def home(request):
if request.method=="POST":
img = UploadForm(request.POST, request.FILES)
if img.is_valid():
print_file_contents(request.FILES[img])
img.save()
return HttpResponseRedirect(reverse('fileupload'))
else:
img=UploadForm()
images=Upload.objects.all()
return render(request,'home.html',{'form':img,'images':images})
Here is my home.html:
{% load staticfiles %}
<link rel="stylesheet" type="text/css" href="{% static 'uploader/style.css' %}" />
<div style="padding:40px;margin:40px;border:1px solid #ccc">
<body>
<center><h2>Here Be Dragons</h2></center>
<p>Lorem ipsum...</p>
<p></p>
</body>
<center><form action="#" method="post" enctype="multipart/form-data">
{% csrf_token %} {{form}}
<input type="submit" value="Upload" />
</form></center><p></p><p>Uploaded files:</p>
{% for img in images %}
{{forloop.counter}}.<a href="{{ img.pic.url }}">{{ img.pic.name }}</a>
({{img.upload_date}})<hr />
{% endfor %}
</div>
And here is the Traceback:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/upload/
Django Version: 1.6.5
Python Version: 2.7.0
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'uploader')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "c:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
112. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Douglas\Desktop\sample\uploader\views.py" in home
14. print_file_contents(request.FILES[img])
File "c:\Python27\lib\site-packages\django\utils\datastructures.py" in __getitem__
301. raise MultiValueDictKeyError(repr(key))
Exception Type: MultiValueDictKeyError at /upload/
Exception Value: '<uploader.models.UploadForm object at 0x000000000340AEF0>'
Does anyone know how I can modify the line print_file_contents(request.FILES[img])
in views.py or any other part of the workflow so as to be able to print the contents of the uploaded file? I would be very grateful for any advice you can offer.
I'm not sure what you are trying to do here. img
represents the entire form itself, not the image field. The image field is called "pic", so request.FILES['pic']
would work.
You could have discovered this yourself by printing or logging request.FILES.keys()
in your view.