6

I am a total beginner to programming and Django so I'd appreciate help that beginner can get his head round!

I was following a tutorial to show how to upload images to an Amazon S3 account with the Boto library but I think it is for an older version of Django (I'm on 1.1.2 and Python 2.65) and something has changed. I get an error: Exception Type: TypeError Exception Value: 'InMemoryUploadedFile' object is unsubscriptable

My code is:

Models.py:

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

class PhotoUrl(models.Model):
    url = models.CharField(max_length=128)
    uploaded = models.DateTimeField()
    def save(self):
        self.uploaded = datetime.now()
        models.Model.save(self)

views.py:

import mimetypes
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse
from django import forms
from django.conf import settings
from boto.s3.connection import S3Connection
from boto.s3.key import Key

def awsdemo(request):   
def store_in_s3(filename, content):
    conn = S3Connection(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
    b = conn.create_bucket('almacmillan-hark')
    mime = mimetypes.guess_type(filename)[0]
    k = Key(b)
    k.key = filename
    k.set_metadata("Content-Type", mime)
    k.set_contents_from_strong(content)
    k.set_acl("public-read")

photos = PhotoUrl.objects.all().order_by("-uploaded")
if not request.method == "POST":
    f = UploadForm()
    return render_to_response('awsdemo.html', {'form':f, 'photos':photos})

f = UploadForm(request.POST, request.FILES)
if not f.is_valid():
    return render_to_response('awsdemo.html', {'form':f, 'photos':photos})

file = request.FILES['file']
filename = file.name
content = file['content']
store_in_s3(filename, content)
p = PhotoUrl(url="http://almacmillan-hark.s3.amazonaws.com/" + filename)
p.save()
photos = PhotoUrl.objects.all().order_by("-uploaded")   
return render_to_response('awsdemo.html', {'form':f, 'photos':photos})

urls.py:

(r'^awsdemo/$', 'harkproject.s3app.views.awsdemo'), 

awsdemo.html:

<div class="form">
    <strong>{{form.file.label}}</strong>
    <form method="POST" action ="." enctype="multipart/form-data">
        {{form.file}}<br/>
        <input type="submit" value="Upload">
    </form> 
</div>  

I'd really appreciate help. I hope I have provided enough code.

Kind regards AL

1
  • 2
    One thing I see right off the bat: k.set_contents_from_strong(content) should really be set_contents_from_string. Commented Aug 6, 2010 at 17:10

2 Answers 2

8

I think your problem is this line:

content = file['content']

From the Django docs:

Each value in FILES is an UploadedFile object containing the following attributes:

  • read(num_bytes=None) -- Read a number of bytes from the file.
  • name -- The name of the uploaded file.
  • size -- The size, in bytes, of the uploaded file.
  • chunks(chunk_size=None) -- A generator that yields sequential chunks of data.

Try this instead:

content = file.read()
Sign up to request clarification or add additional context in comments.

Comments

0

Have you tried Django Storages? That way you only have to specify a storage backend (s3boto in this case) either as the default storage backend, or supply it as an argument to a FileField or ImageField class.

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.