在django中更改文件名

时间:2012-05-28 03:24:13

标签: python django file-upload django-admin

我有这个型号......

class MyModel(models.Model):
    ...
    file = models.FileField(upload_to='files/',null=True, blank=True)
    ...

当我上传文件时,示例文件名为docfile.doc。当我更改文件或我重写文件并再次上传docfile.doc时,文件将变为docfile_1.doc,旧的docfile.doc仍然存在。

我正在django-admin

上传和保存数据

我的问题是,如果我上传新的docfile.doc并且文件名仍为docfile.doc,我如何删除旧版docfile.doc

在我的情况下,任何人都可以帮助我吗?提前谢谢

我试试这个:

def content_file_name(instance, filename):
    print instance
    print filename
    file = os.path.exists(filename)
    print file
    if file:
        os.remove(filename)
    return "file/"+str(filename)

 class MyModel(models.Model):
        ...
        file = models.FileField(upload_to=content_file_name,null=True, blank=True)
        ...

但没有任何结果,当我再次上传docfile.doc时,它会变为docfile_1.doc而旧的docfile.doc仍然存在。

4 个答案:

答案 0 :(得分:2)

我不知道该怎么做,但我认为这些链接可以帮到你:

Here您可以找到FileField接受的两个选项。我认为最让你感兴趣的是FileField.storage。您可以在该参数中传递存储对象。

它说:

  

FileField.storage:可选。存储对象,用于处理文件的存储和检索。

然后,如果您阅读this,您会看到您可以编写自己的存储对象。 Here是如何做到的一些解释。我认为您可以覆盖_save方法以完成您想要做的事情(即:如果该文件已存在,请在保存新副本之前将其删除。)

但要小心!我不知道你要存储的文件的来源是哪一个。也许,你的应用程序将收到许多具有相同名称的文件,尽管它们都不同。在这种情况下,您可能希望使用callable作为FileField.upload_to参数,以便为您的站点接收的每个文件确定唯一的文件名。

我希望这可以帮到你!

答案 1 :(得分:1)

我明白了...我用这个

def content_file_name(instance, filename):
    print instance
    print filename
    file = os.path.exists("media/file/"+str(filename))
    print file
    if file:
        os.remove("media/file/"+str(filename))
    return "file/"+str(filename)

答案 2 :(得分:0)

您还可以在这里查看:ImageField overwrite image file with same name

定义您自己的存储并覆盖其get available_name方法。

答案 3 :(得分:0)

下一个代码可以解决您的问题。您可以覆盖pre_save方法,其中image实际上已保存到存储中。请重命名项目的功能。将新创建的图像字段 ImageFieldWithPermantName upload_to 函数(content_file_name)一起使用。

如果代码太复杂,您可以简化它。我使用代码执行更复杂的上传图像操作:我在自定义_save_image函数中即时创建缩略图。所以,你可以简化它。

from PIL import Image
import StringIO
from django.db.models import ImageField
from django.db.models.fields.files import FileField
from dargent.settings import MEDIA_ROOT
import os

class ImageFieldWithPermanentName( ImageField ):
    def pre_save( self, model_instance, add ):
        file = super( FileField, self ).pre_save(model_instance, add)
        if file and not file._committed:
            if callable( self.upload_to ):
                path = self.upload_to( model_instance, "" )
            else:
                path = self.upload_to
            file.name = path # here we set the same name to a file
            path = os.path.join( MEDIA_ROOT, path )
            chunks = _get_chunks( file.chunks() )
            _save_image( chunks, path )

        return file     

def _get_chunks( chunks ):
    chunks_ = ""
    for chunk in chunks:
        chunks_ += chunk
    return chunks_

def _get_image( chunks ):
    chunks_ = ""
    for chunk in chunks:
        chunks_ += chunk

    virt_file = StringIO.StringIO( chunks_ )
    image = Image.open( virt_file )
    return image

def _save_image( chunks, out_file_path ):
    image = _get_image( chunks )
    image.save( out_file_path, "JPEG", quality = 100 )