Reputation: 2661
I want to change an image name and it's storage location on upload.
I have
def name_func(instance, filename):
blocks = filename.split('.')
ext = blocks[-1]
filename = "%s.%s" % (instance.id, ext)
return filename
class Restaurant(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
image_file = models.ImageField(upload_to=name_func,null=True)
class Bar(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4)
image_file = models.ImageField(upload_to=name_func,null=True)
This uploads all the image files into the media folder and gives it the instance's id as a name.
Now I want the image files to be uploaded into two different subfolders. So I tried using the system filestorage:
fs_restaurant = FileSystemStorage(location='media/restaurant')
fs_bar = FileSystemStorage(location='media/bar')
and then change the image_file
field to:
image_file = models.ImageField(upload_to=name_func,null=True, storage=fs_restaurant)
and
image_file = models.ImageField(upload_to=name_func,null=True, storage=bar)
Now this saves the files in the correct folder structure, however, when I click on the links in the admin's panel it's not linked correctly. This is obviously to the name_func
function, but I am wondering if there is a way to correct that? In the doc I couldn't find a naming function in storage class.
Any ideas on how to fix that ?
Upvotes: 2
Views: 2034
Reputation: 8026
I think your problem is that you need to prepend the subfolder onto your file name and return that. In your database the filename should be the relative path to your file from the STATIC_URL
or MEDIA_URL
.
Here's an example I have where I generate a UUID for the filename and put it in a subfolder called app_images
.
def unique_filename(instance, filename):
path = 'app_images'
filetype = os.path.splitext(instance.image.name)[1]
new_filename = "{}{}".format(uuid.uuid4().hex, filetype)
while AppImage.objects.filter(image__contains=new_filename).exists():
new_filename = "{}{}".format(uuid.uuid4().hex, filetype)
instance.filename = filename
return os.path.join(path, new_filename)
Upvotes: 2