2011-03-18 84 views
1

我有一个模型,里面有一个ImageField。我已经设定的upload_to并创建了自己的FileSystemStorage类来处理保存文件的一个独特的名字......但是......django ImageField - 如何自定义名称+删除旧文件

这种设置可以让我上传和保存文件用每个文件都有唯一的名称(这很好),但我也需要它删除以前存在的文件,例如

我上传file1.png和它保存为file1_xkdeujg.png(这只是一个随机字符串)

然后我进入Django管理(使用Django管理接口,因此需要通过模型进行),并改变图像这一领域的fileNEW.png

需要什么,现在发生的是:

1)它保存新文件fileNEW_fjewiejk.png(独特的随机字符串保存每次图像) -

2)它保存新文件到数据库 -

3)它删除旧文件 - file1_xkdeuig.png - 从文件系统 - 没有做过

问:谁能帮我点3?

一些代码:

class Page(models.Model): 
    image   = models.ImageField(upload_to='pages/', storage=MyFileSystemStorage()) 

和(借用大量从其他地方这个代码的...):

class MyFileSystemStorage(FileSystemStorage): 

    def get_valid_name(self, name): 
      file_root, file_ext = os.path.splitext(name) 
      return "%s_%s%s" % (file_root, rand_key(8), file_ext) 

    def get_available_name(self, name): 
      dir_name, file_name = os.path.split(name) 
      file_root, file_ext = os.path.splitext(file_name) 
      count = itertools.count(1) 
      while self.exists(name): 
        name = os.path.join(dir_name, "%s_%s%s" % (rand_key(32), count.next(), file_ext)) 
      return name 

回答

1

答案来自StackOverflow上一个类似的问题...

基本上,你存储在初始化方法原始图像,然后检查,看它是否之前已经保存更改。

保存后,删除存储在原始图像路径中的图像。

也看到这个答案(乔希的答案是我用过的,因为它没有击中数据库)。

Django: When saving, how can you check if a field has changed?

0

如果我理解正确的,如果重命名文件,比该文件被复制而不是移动。覆盖Page类的保存方法可以让您访问旧的和露水的实例。 http://docs.djangoproject.com/en/dev/topics/db/models/#overriding-model-methods

所有你需要做的是保存旧文件名中的变量,然后调用super.save()后,你可以在案件 os.system("rm "+path_to_file) 当文件发生变化。 这有帮助吗?

+0

是的 - 有道理。查看我的答案,查看我在此使用的答案的链接。 – 2011-03-18 15:44:12

+0

而不是os.system(“rm”+路径),你应该用os.remove(path)直接删除文件。如果你没有验证你的输入,你可能会让任意人在你的服务器上运行任何代码。例如如果path_to_file设置为“image.png; rm -rf /”会怎么样?然后你的服务器将执行该操作。 – Rory 2011-09-29 10:44:00

+0

加上它更好,因为它使用标准库调用而不是分支shell并运行命令。 – sleblanc 2013-02-07 01:39:41