Skip to main content
 首页 » 编程设计

python之Django ImageField/FileField 使用模型的 pk 保存上传的文件

2025年05月04日37hnrainll

我正在转换一个遗留站点(最初是用 Rails 编写的),默认情况下,图像是使用 {{pk}}.{{extension}} 格式保存的,并且该文件总是被覆盖如果上传了新文件。 我想用这个 django 版本继续这种格式。

我最初认为扩展 FileSystemStorage 是可行的方法,但我不知道有什么方法可以将当前模型对象传递给它。有人对实现此目的的“django 方式”有建议吗?

如果我需要编写自己的类来扩展 ImageField 来管理它,那就这样吧。 :) 只是想知道我是否遗漏了一些简单的东西。

[edit] 我做了什么,基于 surfeurx 和 DrTyrsa 的回答:

temp_image = None 
 
def image_path(self, uploaded_file_name): 
    prefix = 'designs/' 
    extension = os.path.splitext(uploaded_file_name)[-1] 
    if self.pk != None: 
        return prefix + str(self.pk) + extension 
    else: 
        tmp_name = str(uuid.uuid4()) 
        self.temp_image = prefix + tmp_name + extension 
        return self.temp_image 
 
image_upload = models.ImageField(upload_to=image_path, null=True, blank=True)  
 
def save(self): 
    self.updated_at = datetime.now() 
 
    is_new = self.pk == None 
    super(Design, self).save() 
 
    if is_new: 
        if self.temp_image != None: 
            os.rename(MEDIA_ROOT + self.temp_image, MEDIA_ROOT + self.image_path(self.temp_image)) 
            self.temp_image = None 

我现在遇到的真正问题是我想让它覆盖图像。这将提供正确的文件名,但看起来我必须扩展 ImageField 才能覆盖它。找到了这个小家伙:http://djangosnippets.org/snippets/636/

请您参考如下方法:

您可以像这样使用 upload_to:

def image_path(instance, filename): 
    return instance.id + os.path.splitext(filename)[1] 
 
class Brand(models.Model): 
    ... 
    logo = models.ImageField(upload_to=image_path, null=True, blank=True)