Я пытаюсь проверить существующий файл и перезаписать его, пока я могу сделать это с помощью пользовательского хранилища, которое выглядит примерно так
from django.core.files.storage import FileSystemStorage
class DuplicateFileStorage(FileSystemStorage):
def get_available_name(self, name, max_length=None):
return name
def _save(self, name, content):
if self.exists(name):
self.delete(name)
return super(DuplicateFileStorage, self)._save(name, content)
Приведенный выше класс проверяет существующийфайл и удаляет его.
И модель, которую он ищет:
class DataStorageModel(models.Model):
user = models.ForeignKey(User, related_name='data_storage', on_delete=models.CASCADE)
file_name = models.CharField(blank=True, max_length=200, help_text="File Name")
file = models.FileField(blank=True, null=True, upload_to=user_directory_path, storage=DuplicateFileStorage())
relative_path = models.CharField(blank=True, max_length=200, help_text="Relative Path if folder else null")
def delete(self, using=None, keep_parents=False):
self.file.delete()
return super(DataStorageModel, self).delete()
Проблема в том, что, хотя он удаляет и записывает тот же файл, он также создает новую запись модели с тем жесуществующий путь, то есть, если я загружаю один и тот же файл дважды, я получаю один файл в пути ОС, но две записи модели.Примерно так (здесь есть изображение):
![screenshot](https://i.imgur.com/2gY00Mv)
Поэтому я попытался использовать метод clean()
с self.file.storage.exists(self.file.name)
(согласно this ) но я получаю существование как False
, хотя там есть файл.
def save(self, force_insert=False, force_update=False, using=None,
update_fields=None):
self.full_clean()
return super(DataStorageModel, self).save()
def clean(self):
print(self.file.storage.exists(self.file.name)) # <--- False
Поэтому мой вопрос: как мне проверить, существует ли дублирующий файл, перезаписатьфайл, но не создать новую запись?
Редактировать
Я забыл вставить user_director_path()
:
def user_directory_path(instance, filename):
"""
If relative path is not ``null`` the files will be stored as is else it will be
stored to the root directory.
"""
if instance.relative_path != 'null':
return 'user_{0}{1}'.format(instance.user.id, instance.relative_path)
return 'user_{0}/{1}'.format(instance.user.id, filename)
Я думаю,Я получил это, если я сделаю это:
def clean_fields(self, exclude=None):
if self.file.storage.exists('user_{0}{1}'.format(self.user.id, self.relative_path)):
raise ValidationError('File already exists.')
Это работает, но вся загрузка не удалась, даже перезапись файлов