多亏了alTus的回答,我才知道编写
自定义存储类
是关键,而且比预期的要容易。
- 我只是省略了调用超类
_save
方法来写文件(如果文件已经存在的话),而我只是返回名称。 - 我覆盖
get_available_name
,以避免在文件名已经存在的情况下,在文件名后附加数字
我不知道这是否是 正确的 方法,但到目前为止效果很好。
希望这是有用的!
这是完整的示例代码:
import hashlibimport osfrom django.core.files.storage import FileSystemStoragefrom django.db import modelsclass MediaFileSystemStorage(FileSystemStorage): def get_available_name(self, name, max_length=None): if max_length and len(name) > max_length: raise(Exception("name's length is greater than max_length")) return name def _save(self, name, content): if self.exists(name): # if the file exists, do not call the superclasses _save method return name # if the file is new, DO call it return super(MediaFileSystemStorage, self)._save(name, content)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): # use the custom storage class fo the FileField orig_file = models.FileField( upload_to=media_file_name, storage=MediaFileSystemStorage()) 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)


