Question

I need to upload an image to a Django ImageField, but due to a restriction based on a third party API, I need the images to be uploaded to the media directory without a subdirectory.

The restriction is due to the fact that the filename stored locally (in the imagefield column) is used to calculate a hash to request that image from a media API, so the field must contain the same name as the filename in the API, unfortunately the API filename cannot contain slashes.

I can't add a field to the db to store the real filename, nor can I control the code that returns the calculated hash.

I tried making the upload_to a callable that returns an empty string, which seems to get around the upload_to required error, but the images are all then saved as just ''(blank) _1, _2 ... etc without the rest of the image name.

I have also tried making the upload_to return '/', '../media', '../media/' all to no avail (a variety of errors or malformed filenames)

So TL;DR how to save images directly to MEDIA_ROOT, without a sub directory?

EDIT, extra info:

So I just tried a little hack that does part of it:

from django.core.files.storage import FileSystemStorage

media_root_store = FileSystemStorage(location='/path/to/media/parent')

class MyModel(models.Model):
    img_file = models.ImageField(
        max_length=255,
        upload_to='media',
        storage=media_root_store)

This dirty hack saves the image to the correct location, though it still obviously saves the image path with media/ appended. So I'm unsure if it has actually gotten me any closer.

Was it helpful?

Solution

Turns out there was a pretty big clue in the error from my earlier attempt (the one generating _1, _2 etc)

If I specify an upload_to callable that simply returns the filename argument, then the image will be saved directly in the MEDIA_ROOT, with the correct filename saved in the database (without the directory prefix).

I had been under the impression that upload_to will just provide a path to append to MEDIA_ROOT, which will then have the image filename appended to that. Turns out this is incorrect.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top