Django帮助函数来重命名用户上传的图像

bvpmtnay  于 2022-12-14  发布在  Go
关注(0)|答案(1)|浏览(127)

对于一个django项目,我有一个模型,它有一个图像字段,这个想法是用户上传一个图像,django根据选择的模式重命名它,然后将它存储在媒体文件夹中。
为了达到这个目的,我在一个单独的文件utils.py中创建了一个helper类。这个类可以在django ImageField模型的upload_to参数中调用。图像应该通过连接创建的项目的.name和.id属性来重命名。我的解决方案的问题是,如果图像在创建新的项目对象时被上传,则没有.id值可供使用(目前还没有)。因此,我们不必说:banana_12.jpg我得到了banana_None. jpg。如果我上传了一个已经存在的物品对象上的图像,那么这个图像会被正确地重命名。这是我的解决方案。我如何改进代码,使它也能在新的物品对象上工作?有更好的方法吗?

# utils.py

from django.utils.deconstruct import deconstructible
import os

@deconstructible
class RenameImage(object):
    """Renames a given image according to pattern"""

    def __call__(self, instance, filename):
        """Sets the name of an uploaded image"""
        self.name, self.extension = os.path.splitext(filename)
        self.folder = instance.__class__.__name__.lower()
        
        image_name = f"{instance}_{instance.id}{self.extension}"

        return os.path.join(self.folder, image_name)

rename_image = RenameImage()
# models.py

from .utils import rename_image

class Item(models.Model):
    # my model for the Item object
    name = models.CharField(max_length=30)
    info = models.CharField(max_length=250, blank=True)
    image = models.ImageField(upload_to=rename_image, blank=True, null=True) # <-- helper called here
    # ...

我创建了帮助器类RenameImage,由于上面解释的原因,只有当对象已经存在时,它才能正确工作。

9jyewag0

9jyewag01#

It is not possible because the id is assigned after saving. You have to use a post_save signal and then change the filename To do this add signal.py under app In the apps.py file, override the ready function to add the signals.py import statement
apps.py

from django.apps import AppConfig

class AppNameConfig(AppConfig):
    name = 'app_name'

    def ready(self):
        import app_name.signals

On init.py set default app config

init.py

default_app_config = 'app_name.apps.AppNameConfig'

signals.py

from django.db.models.signals import post_save
from django.dispatch import receiver

from .models import Item

@receiver(post_save, sender=Item)
def post_save(sender, instance: FilettoPasso, **kwargs):
    if kwargs['created']:        
        print(instance.id)
        instance.image.path = new path
        # rename file in os path
        ...
        instance.save()

相关问题