我有一个带FileField
的模型,它保存用户上传的文件。既然我想节省空间,我想避免重复。
我希望实现的目标:
1和2已经可以工作了,但是我如何才能忘记上传的副本并使用现有文件?
请注意,我希望保留现有文件并且不覆盖它(主要是保持修改的时间不变-更好地用于备份)。
注意:
django.core.files.uploadhandler.TemporaryFileUploadHandler
代码:
def media_file_name(instance, filename):
h = instance.md5sum
basename, ext = os.path.splitext(filename)
return os.path.join('mediafiles', h[0:1], h[1:2], h + ext.lower())
class Media(models.Model):
orig_file = models.FileField(upload_to=media_file_name)
md5sum = models.CharField(max_length=36)
...
def save(self, *args, **kwargs):
if not self.pk: # file is new
md5 = hashlib.md5()
for chunk in self.orig_file.chunks():
md5.update(chunk)
self.md5sum = md5.hexdigest()
super(Media, self).save(*args, **kwargs)
感谢您的帮助!
不过,使用save/delete方法很难实现这一点,因为z文件的处理非常具体。
但你可以试试这样的短信。
首先,我的简单md5文件哈希函数:
下一个
simple_upload_to
是smth,类似于您的媒体文件名函数。 你应该这样使用它:当然,这只是一个例子,因此路径生成逻辑可以是多种多样的。
最重要的是:
如您所见,此自定义存储在保存之前删除文件,然后用相同的名称保存新文件。 因此,如果不删除(并因此更新)文件很重要,可以在这里实现逻辑。
有关存储的详细信息,请访问:https://docs.djangoproject.com/en/1.5/ref/files/storage/
多亏了alTus的回答,我才发现写一个custom storage class是关键,而且比预期的要容易。
_save
方法来编写文件(如果它已经存在)并返回名称。get_available_name
,以避免在已经存在同名文件时在文件名后面附加数字我不知道这是不是做这件事的正确方法,但到目前为止效果还不错。
希望这是有用的!
以下是完整的示例代码:
我有同样的问题,发现这个问题。由于这并不罕见,我在网上搜索了一下,找到了下面的Python包,它可以完全按照您的要求运行:
https://pypi.python.org/pypi/django-hashedfilenamestorage
如果SHA1散列是不可能的,我认为添加MD5散列支持的pull请求将是一个好主意。
相关问题 更多 >
编程相关推荐