我正在尝试检查现有文件并将其覆盖,到目前为止,我已经能够使用自定义存储(看起来像这样)来进行
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()
问题是,尽管它删除并写入了相同的文件,但它还会创建一个具有相同现有路径的新模型条目,也就是说,如果我上载相同的文件两次,则在OS路径中会得到一个文件,但会有两个模型条目。这样的东西(这里有图片):
所以我尝试将clean()
与self.file.storage.exists(self.file.name)
一起使用False
方法(根据this),但是即使那里有文件,我也以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
的形式存在。 / p>
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.')
如果我这样做的话,我想我明白了
"@@MAX_CONNECTIONS"
工作正常,但整个上传失败,甚至没有重写文件
答案 0 :(得分:0)
条件 if instance.relative_path != 'null':
错误。它应该只是 if instance.relative_path:
当我尝试您的代码片段时,我感觉 user_directory_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.
The "relative_path" path should not be start or ends with a slash ("/") but, can use slash inside
/foo/ -> Not allowed
/foo/bar -> Not allowed
foo/bar/ -> Not allowed
foo -> Allowed
foo/bar -> Allowed
foo/bar/foobar -> Allowed
"""
if instance.relative_path:
relative_path = instance.relative_path
if relative_path[0] == '/':
relative_path = relative_path[1:]
if relative_path[:-1] == '/':
relative_path = relative_path[:-1]
return 'user_{0}/{1}/{2}'.format(instance.user.id, relative_path, filename)
return 'user_{0}/{1}'.format(instance.user.id, filename)
现在进入我们的解决方案,我创建了一个示例视图来解决该问题。
from django.http.response import HttpResponse
def foo(request):
if request.method == 'POST':
create_data = {
"user_id": request.user.pk,
"file": request.FILES['file_name']
}
ds_temp = DataStorageModel(**create_data)
path = user_directory_path(ds_temp, ds_temp.file.name)
try:
ds_existing = DataStorageModel.objects.get(file=path)
ds_existing.file = create_data['file']
ds_existing.save()
return HttpResponse("instance modified")
except DataStorageModel.DoesNotExist:
ds_temp.save()
return HttpResponse("new instance created")
return HttpResponse("HTTP GET method")