There are several questions around this topic but not one that I've found that suits what I'm trying to do. I want to be able to upload a file to a model and save that file in a nice location using the model instance attributes like pk. I know that this stuff gets set after model.save()
so I need to write a custom save to do this, but I can't figure it out. Here is what I have:
class UploadModel(models.Model):
image = models.ImageField(upload_to='uploads')
def save(self, *args, **kwargs):
# Call standard save
super(UploadModel, self).save(*args, **kwargs)
if 'uploads' in self.image.path:
initial_path = self.image.path
# New path in the form eg '/images/uploadmodel/1/image.jpg'
new_path = os.path.join(settings.MEDIA_ROOT, 'images',
self._meta.model_name, self.pk, os.path.basename(initial_path))
# Create dir if necessary and move file
if not os.path.exists(os.path.dirname(new_path)):
makedirs(os.path.dirname(new_path))
os.rename(initial_path, new_path)
# Do something here to save the new file to the image field
# Save changes
super(UploadModel, self).save(*args, **kwargs)
What do I have to do to the image
field to get it to reference this new file location, and set all the useful attributes to it like image.path
, image.name
, image.url
etc?
The docs say that the above is all I should need to do but this just results in the image
field pointing to a file that doesn't exist. I've looked at this related question and tried the snippet mentioned in one of the answers but I have not found a solution yet.