13

I noticed that django-storages (or perhaps it's Django's storage API itself) overwrites files with the same name. This is a problem for me as my site allows user uploads, so I need to ensure that files are never overwritten.

Ideally I'd like to be able to pass a file name to the storage backend from the view level, but I'm struggling to find an elegant way to do this. I'd be equally happy if there's a switch somewhere where I can just do something like overwrite=False and have the backend come up with its own alternative name.

Wayne Koorts
  • 10,861
  • 13
  • 46
  • 72

2 Answers2

30

If you are using the s3boto backend not the old s3 backend in django-storages then you can change this using the AWS_S3_FILE_OVERWRITE setting: https://bitbucket.org/david/django-storages/src/83fa2f0ba20c/storages/backends/s3boto.py#cl-43

Mark Lavin
  • 24,664
  • 5
  • 76
  • 70
  • 1
    What if I only want to do this on one specific model and not system wide? – Chad Jun 28 '21 at 18:16
  • 1
    The link from the answer has expired. Here is the working [docs](https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html#:~:text=aws_s3_file_overwrite) – Yevhen Bondar May 01 '22 at 14:26
  • For one specific model, you can create a custom file storage (for S3, use `storages.backends.s3boto3.S3Boto3Storage` as base) & then set `file_overwrite` property to `False` in that. You can then pass your custom storage class as argument to the file or image field(s) in your model. – shad0w_wa1k3r Oct 29 '22 at 21:34
1

@Mark Lavin's answer aptly points out that setting AWS_S3_FILE_OVERWRITE to False avoids this problem.

You may additionally want to improve your file name-spacing a little bit. You can save files under whatever name on S3 you want (it doesn't have to be the name of the file the user uploaded). So you could save your file with the name "user_uploads/[user_id]/[user_generated_file_name]". You can also set the file name to be whatever you want as part of a download. If you save the user's uploaded file name as a field on your model, you can then specify that as the file name in the view that downloads a file.

Zags
  • 37,389
  • 14
  • 105
  • 140