如果我有一个带有FileField的Django模型,例如
class Probe(models.Model):
name = models.CharField(max_length=200, unique=True)
nanoz_file = models.FileField(upload_to='nanoz_file', blank=True)
如果用户在管理界面中上传新文件,有没有办法阻止上传的文件被覆盖?
另外,如果我保留旧文件,有没有办法将以前的文件与模型实例联系起来?
即,我希望能够列出上传到给定模型实例的nanoz_file字段的所有文件。
答案 0 :(得分:3)
Django永远不会覆盖上传的文件。如果你上传'foo.png'两次,那么第二个将是'foo_1.png' - 我刚刚测试了这个,但是不要接受我的话:尝试一下!
所有你需要做的(或让django-reversion做)是跟踪以前的文件名。
答案 1 :(得分:1)
您可以使用此结构:
class File(models.Model):
name = models.CharField()
file = models.FileField(upload_to='files_storage/')
belongs = models.ForeignKey('self')
creation = models.DateTimeField(auto_now_add=True)
然后在视图中你可以使用类似的东西:
def edit_file(request, ...):
# Get the file model instance
file_model = ... # Code to get the instance
# Create a new instance of the model with the old file path
old_file = File(name='file1-v2', file=file_model.file, belongs=file_model)
old_file.save()
# Update the file_model with the new file data
希望这有帮助!
答案 2 :(得分:0)
正如jpic所说,你可以试试django-reversion,或者
对于第二种方式,实际上用于处理所有用户上传,最好按照您设计的模式命名文件,而不是使用原始名称(您也可以存储原始名称以供以后使用)。对于您的情况,由于名称字段是唯一的,因此该字段适合作为生成上载文件的文件名的基础,如果它很少更改:
import os.path
from django.hash_compat import sha_constructor
def upload_to(self, filename):
return 'nanoz_file/%s%s' % (
sha_constructor(self.name).hexdigest(), os.path.splitext(filename)[-1])
class Probe(models.Model):
name = models.CharField(max_length=200, unique=True)
nanoz_file = models.FileField(upload_to=upload_to, blank=True)
然后在您的视图中,您可以通过
获取Probe实例探测的所有文件的名称列表import glob
# be careful to operate directory securely
glob.glob(os.path.join(
os.path.dirname(probe.nanoz_file.path),
'%s*' % sha_constructor(probe.name).hexdigest()))