jdriscoll/django-imagekit — pull request #111 by claymation (2012-02-29 10:31:54+00:00)
Title: Wrap ContentFile in a file-like object with a filename and content_type.

We use ImageKit to scale images and Rackspace Cloud (formerly Mosso) to serve them. Unfortunately, we've found that our scaled images (spec files) are served with an incorrect Content-Type—`application/octet-stream`—causing browsers to download the images instead of displaying them. Our original source images, however, *are* served with the correct Content-Type, and they are also hosted on Rackspace Cloud. So what gives?

When users upload files to our site, Django reads the content type from the multipart MIME header and sets a `content_type` attribute on the UploadedFile object created to handle the uploaded file. The django-storages Mosso back-end that we use then references that `content_type` attribute when posting the file to Rackspace Cloud, allowing that file to be served with the appropriate Content-Type header.

ImageKit does not set such an attribute, however, so neither django-storages nor the cloudfiles storage backend can set a content type when saving the spec files out to the cloud. This patch adds an extra layer of indirection that allows us to tack some attributes (`name` and `content_type`) onto the underlying `ContentFile`—which we can't do with `StringIO` since that's a native type.

I debated whether I should modify ImageKit, django-storages, or the cloudfiles backend, but ultimately decided ImageKit was the right place since django-storages and cloudfiles already provide mechanisms to set content type (by deferring to the content_type or name of the source file), and Django accommodates that by setting a content_type attribute on uploaded files. Setting name and content_type in ImageKit seems like a simple and inexpensive solution (work-around?) to the problem.