Django-storages: Second file upload override first one, if have same name

Created on 8 Jun 2015  路  9Comments  路  Source: jschneier/django-storages

Here is the scenario:

  • Model Product has a image field;
  • User uploads an image to its product
  • Another user uploads another image to another product
  • First image gets overriden.

Is it a problem that django-storages should fix or should I rename the file to make it unique by user?

Most helpful comment

What backend are you using? If s3boto, the problem might be that the default is AWS_S3_FILE_OVERWRITE = True. This makes sense for static files but not for media files.

You probably want a separate storage class for media, something like this:

class MediaS3BotoStorage(S3BotoStorage):
     location = 'media'
     file_overwrite = False  # override default AWS_S3_FILE_OVERWRITE=True

All 9 comments

At this time, I'll solve by creating folders by users:

import os
def get_upload_path(instance, filename):
    return os.path.join(
      "user_%d" % instance.owner.id, "car_%s" % instance.slug, filename)

then:

photo = models.ImageField(upload_to=get_upload_path)

What backend are you using? If s3boto, the problem might be that the default is AWS_S3_FILE_OVERWRITE = True. This makes sense for static files but not for media files.

You probably want a separate storage class for media, something like this:

class MediaS3BotoStorage(S3BotoStorage):
     location = 'media'
     file_overwrite = False  # override default AWS_S3_FILE_OVERWRITE=True

If you are only using storages for user media and not for static media, then you can simply add the setting: AWS_S3_FILE_OVERWRITE = False

That saved my skin! Thanks @agriffis . Maybe we should include that in documentation?

Where would be the best place to document this? I can to that.

+1

EDIT: I had to clear cache to see the overwritten file.

  • 1 please document this early on people on heroku will hit this and be confused(helping friend on heroku)

This is documented.

If you are only using storages for user media and not for static media, then you can simply add the setting:聽AWS_S3_FILE_OVERWRITE = False

Isn't AWS_S3_FILE_OVERWRITE = False OK for both static and media files?
Django's collectstatic command will delete existing file before copy a new one:

    def copy_file(self, path, prefixed_path, source_storage):
        """
        Attempt to copy ``path`` with storage
        """
        # Skip this file if it was already copied earlier
        if prefixed_path in self.copied_files:
            return self.log("Skipping '%s' (already copied earlier)" % path)
        # Delete the target file if needed or break
        if not self.delete_file(path, prefixed_path, source_storage):
            return
        # The full path of the source file
        source_path = source_storage.path(path)
        # Finally start copying
        if self.dry_run:
            self.log("Pretending to copy '%s'" % source_path, level=1)
        else:
            self.log("Copying '%s'" % source_path, level=1)
            with source_storage.open(path) as source_file:
                self.storage.save(prefixed_path, source_file)
        self.copied_files.append(prefixed_path)

Does it make sense?

Was this page helpful?
0 / 5 - 0 ratings