Django ImageField/FileField save uploaded file using model's pk

3.8k views Asked by At

I'm converting a legacy site (originally written in rails) and by default the images were saved using the format {{pk}}.{{extension}} and that file was always overwritten if a new file is uploaded. I'd like to continue that format with this django version.

I originally thought extending FileSystemStorage would be te way to go, but I don't know of a way to pass the current model object to it. Anyone have a suggestion on a "django way" to accomplish this?

If I need to write my own class that extends ImageField to manage this, then so be it. :) Just wondering if there was something simple I'm missing.

[edit] WHAT I DID, BASED ON ANSWER FROM surfeurx and 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

The real problem I'm having now is that I want it to overwrite the image. This will provide the right file name, but it looks like I'm going to have to extend ImageField to get it to overwrite. Found this little guy: http://djangosnippets.org/snippets/636/

2

There are 2 answers

1
surfeurX On BEST ANSWER

You can use upload_to like:

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)
0
DrTyrsa On

You need to define upload_to function. It accepts instance as an argument. But don't forget that if you are creating the instance it won't have pk yet (but you can save it first, and then save the image).