I have a Django model for a Book which has a slug
field that's a hash based on its pk
. It also has a thumbnail
which is saved to a path including that slug
.
In Admin, if I create and save the Book without a thumbnail, and then add the thumbnail and save the Book again, this works: the thumbnail is saved to /media/books/<slug>/foo.jpg
.
BUT if I create the Book with a thumbnail image, and save it, the thumbnail is saved before the slug
can be generated, so it's saved to /media/books/foo.jpg
. This because files are saved before the model.
I'd like to always include slug
in the thumbnail's path, but I can't work out how to delay saving the thumbnail until after the slug
has been generated. Any ideas?
from django.db import models
from hashes import Hashids
def upload_path(instance, filename):
return "/".join([books, instance.slug, filename])
class Book(models.Model):
title = models.CharField(null=False, blank=False, max_length=255)
slug = models.SlugField(max_length=10, null=False, blank=True)
thumbnail = models.ImageField(
upload_to=upload_path, null=False, blank=True, default=""
)
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
if not self.slug:
# Now we have a pk, generate a slug if it doesn't have one.
hashids = Hashids(salt="my salt", min_length=5)
self.slug = hashids.encode(self.pk)
kwargs["force_insert"] = False
self.save(*args, **kwargs)
(I know that Hashids aren't secure; that someone could figure out the pk
from the slug
. I'm fine with that for this use case.)