Reputation: 231
The goal is to update the content of an existent file identified by 'filename'.
The first save call (aStorage.save(filename, ContentFile(content1)) creates the file 'test1'.
The second save call (aStorage.save(filename, ContentFile(content2))) creates a new file (done by Storage.get_available_name) instead of updating the current one.
>>> from django.core.files.storage import FileSystemStorage
>>> from django.core.files.base import ContentFile
>>> import sys
>>> sys.path.append('/home/project1')
>>> import os
>>> os.environ['DJANGO_SETTINGS_MODULE']='project1.settings'
>>> from django.conf import settings
>>> aStorage = FileSystemStorage(location=settings.BASE_DIR)
>>> content1 = "1514 – Mary Tudor (pictured), sister of Henry VIII of England"
>>> content2 = "1874 – The Universal Postal Union, then known as the General Postal"
>>> filename = os.path.join(settings.BASE_DIR, 'tests', 'test1')
>>> aStorage.save(filename, ContentFile(content1))
'./tests/test1'
>>> aStorage.save(filename, ContentFile(content2))
'./tests/test1_ESZ5jdM'
One solution might be this one here:
>>>>if (aStorage.exists(filename)):
>>>> aStorage.delete(filename)
>>> aStorage.save(filename,ContentFile(content2))
`'./tests/test1'`
Is there any other mechanism/workaround to achieve the same functionality ? Thank you.
Upvotes: 2
Views: 2311
Reputation: 231
It's not clear to me in which situation I can use save method. Therefore, for the moment, I prefer not to change/overwrite the Django Storage.save/get_available_name method behavior. This sounds like another solution to my problem : to use the Storage.open method instead of Storage.save:
>>> content1 = "11111111"
>>> content2 = "22222222"
>>> aStorage
<django.core.files.storage.FileSystemStorage object at 0x7f94ffccc6d0>
>>> fd = aStorage.open("test1.txt","w+")
>>> fd.write(content1)
8
>>> fd.seek(0)
0
>>> fd.read()
'11111111'
>>> fd.close()
>>>
>>> fd = aStorage.open("test1.txt","w+")
>>> fd.read()
''
>>> fd.write(content2)
8
>>> fd.seek(0)
0
>>> fd.read()
'22222222'
>>> fd.close()
>>> aStorage.exists("test1.txt")
>>> True
I will appreciate if you could share with me a situation for the usage of Django's Storage.save method. I am looking here a real case situation. Thanks.
Upvotes: 0
Reputation: 3230
IF you want to "overwrite" the file, you can go with your own custom Filestorage like this:
class MyFileSystemStorage(FileSystemStorage):
def get_available_name(self, name):
if os.path.exists(self.path(name)):
os.remove(self.path(name))
return name
In this case the file will be deleted so that a file with the same name can be created. This feels like it would be overwritten. Hope this is what you are looking for.
Update:
MyFileSystemStorage is a small custom class which inherits from FileSystemStorage and overwrites the "default" get_available_name
function from Djangos FileSystemStorage. You do not need to use this function directly. Its transparently handled if you save a FileObject.
You can use it like this:
aStorage = MyFileSystemStorage(location=settings.BASE_DIR)
If you use MyFileSystemStorage instead of Django FileSystemStorage and save a file with a certain name, an already existing file with that name will be deleted and a new one will be created with the given name. Be careful to use the code like this because any existing file will be "overwritten" if it already exists. If I follow your example correctly you want this behaviour, so I think that it wouldnt not have an impact on your existing code.
Upvotes: 1