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

时间:2011-10-21 04:42:12

标签: python django django-file-upload pim

我正在转换遗留站点(最初使用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/

2 个答案:

答案 0 :(得分:3)

您需要定义upload_to功能。它接受instance作为参数。但是不要忘记,如果您创建实例,它将不会有pk(但您可以先保存它,然后保存图像)。

答案 1 :(得分:3)

您可以使用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)