django-storages with Amazon S3 - prevent overwriting - python

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.

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'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.

Related

How to Save file in database instead of upload in server media folder ,using models.FileField?

I want to save a file in database instead of uploading it to a server media file and save URL in Database, I want directly save file in the Database.
Right now I am doing this:
model.py:
File = models.FileField(upload_to='CSR/', null=True , blank = True)
template.html:
<td> {{certificate.File.url}} </td>
Django supports BinaryField which lets you store binary data in the database.
The Django docs state:
Abusing BinaryField
Although you might think about storing files in the database, consider that it is bad design in 99% of the cases. This field is not a replacement for proper static files handling.
If you do not want to store files into the filesystem of your webserver, you can use the django-storages library which provides options for Amazon S3, DigitalOcean and more.

Django FileField Model that doesn't upload but returns path of the file

I am using Django to build an app where I ask the user to choose some files from his/her computer and the app will process them and write an output file in the same directory.
If I use the FileField model in Django, it uploads the file to the MEDIA_ROOT directory. That's not what I want. I would like the file to remain where it is and I need the path to the file where it is instead. I have been looking at the FileField code:
https://docs.djangoproject.com/en/1.11/_modules/django/db/models/fields/files/#FieldFile
Does anyone know of a hack around this where the upload_to is disabled and the storage method that is being used returns the path instead? From what I could make out, the storage method reads the file and writes it into the upload_to directory. The FileField class uses the FieldFile class and the FileDescriptor class. Does anyone know which method actually performs the read and therefore has the actual path of the file? Been trying to read the code but I am not at an advanced stage yet and I can't understand all of it.
Thanks in advance.

In plone how can I make an uploaded file as NOT downloadable?

I wish to make the uploaded file contents only viewable on the browser i.e using atreal.richfile.preview for doc/xls/pdf files. The file should not be downloadable at any cost. How do I remove the hyperlink for the template in a particular folder for all the files in that folder? I use Plone 4.1 There is AT at_download.
Cue tune from Hotel California: "You can check out any time you like, but you can never leave."
You do not not really want to disable all downloading, I believe that you really just want to disable downloads from all users but Owner. There is no practical use for putting files into something with no vehicle for EVER getting them back out...
...so you need to solve this problem with workflow:
Use a custom workflow definition that has a state for this behavior ("Confidential"). Ensure that "View" permission is not inherited from folder above in the permissions for this state, and check "Owner" (and possibly "Manager" if you see fit) as having "View" permission.
Set the confidential state as the default state for files. You can do this using Workflow policy support ("placeful workflows") in parts of the site if you do not wish to do this site-wide.
Should you wish to make the existence of the items viewable, but the download not, you are best advised to create a custom permission and a custom type to protect downloading with a permission other than "View" (but you still should use workflow state as permission-to-role mapping templates).
Script (Python) at /mysite/portal_skins/archetypes/at_download Just customize to contain nothing. Thought this will be helpful to someone who would like to keep files/ image files in Plone confidential by sharing the folders with view permission and disable checkout and copy option for the role created

What's the best way to setup a user post image uploading system?

I'm using django. I want a user to upload an image for a user post, but I'm not sure the backend of this. Should I setup a db with the url of the image, a folder for the user, a folder inside of the post, and the image finally in that folder? What is the best (fastest, efficient, nonconfusing) way of doing this?
You can use the built in django ImageField. This essentially is set up to store and reference a url relative to a media dir on the webserver.
There is a pretty basic example here.
EDIT:
For your own implementation outside of django most people would implement it in a similar way to how Django's imagefield works. Basically, you story a reference to a file in a filesystem somewhere, and store the actual file on the filesystem.
You can store the actual image in the database but I think most people prefer to not store it in the database. This stackoverflow question has a lot of info about why one would want to do it one way or another. I myself have done this both ways and like storing them in the filesystem more than in the database in most cases.
You can use the ImageField which comes built in in with django. The good thing about this it stores and manages it within Django, you can resize and get url to the image all using PIL and Django helper methods.
This is the best way for deployment as well, once you decide to deploy you will be able to tweak the system to best serve up static files, as supposed to managing it yourself.
Goodluck.

Django upload_to outside of MEDIA_ROOT

My deployment script overwrites the media and source directories which means I have to move the uploads directory out of the media directory, and replace it after the upload has been extracted.
How can I instruct django to upload to /uploads/ instead of /media/?
So far I keep getting django Suspicious Operation errors! :(
I suppose another solution might be a symlink?
Many thanks,
Toby.
I did the following:
from django.core.files.storage import FileSystemStorage
upload_storage = FileSystemStorage(location=UPLOAD_ROOT, base_url='/uploads')
image = models.ImageField(upload_to='/images', storage=upload_storage)
UPLOAD_ROOT is defined in my settings.py file: /foo/bar/webfolder/uploads
While the accepted answer is probably what you want, we now have the option with django 3.1 that we can decide which storage to use at runtime by passing a function to the storage argument of an ImageField or FileField.
def select_storage():
return MyLocalStorage() if settings.DEBUG else MyRemoteStorage()
class MyModel(models.Model):
my_file = models.FileField(storage=select_storage)
Have a look at the official docs.
Please note that the current accepted answer writes the actual value of the variable UPLOAD_ROOT to the migration file. This doesn't produce any SQL when you apply it to the database but may be confusing if you change that setting frequently.

Categories

Resources