使用当前模型ID的Django管理文件上传

发布于 2021-01-29 18:41:18

我正在尝试使用默认的Django
admin创建一个简单的相册。我想为每个画廊保存一张样本照片,但是我不想保留filname。除了文件名,我想保存模型的ID(N.jpg)。但是,第一次我要保存该对象时,该ID不存在。我如何知道模型中的下一个自动增量,或者以某种方式保存模型数据(在存在super.save文件时上传之前和之后)self.id?有没有很酷的解决方案?

像这样:

def upload_path_handler(instance, filename):
    ext = filename extension
    return "site_media/images/gallery/{id}.{ext}".format(id=instance.nextincrement, ext=ext)

class Gallery(models.Model):
    name  = models.TextField()
    image = models.FileField(upload_to=upload_path_handler)

也许将文件名存储在其他字段中。

关注者
0
被浏览
52
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    图像文件将在Gallery实例之前保存。因此,您必须通过使用带有状态的Gallery实例本身的信号将保存分为两个阶段:

    from django.db.models.signals import post_save, pre_save
    from django.dispatch import receiver
    
    _UNSAVED_FILEFIELD = 'unsaved_filefield'
    
    @receiver(pre_save, sender=Image)
    def skip_saving_file(sender, instance, **kwargs):
        if not instance.pk and not hasattr(instance, _UNSAVED_FILEFIELD):
            setattr(instance, _UNSAVED_FILEFIELD, instance.image)
            instance.image = None
    
    @receiver(post_save, sender=Image)
    def save_file(sender, instance, created, **kwargs):
        if created and hasattr(instance, _UNSAVED_FILEFIELD):
            instance.image = getattr(instance, _UNSAVED_FILEFIELD)
            instance.save()        
            # delete it if you feel uncomfortable...
            # instance.__dict__.pop(_UNSAVED_FILEFIELD)
    

    upload_path_handler看起来像

    def upload_path_handler(instance, filename):
        import os.path
        fn, ext = os.path.splitext(filename)
        return "site_media/images/gallery/{id}{ext}".format(id=instance.pk, ext=ext)
    

    如果字段仅用于图像上传,我建议使用ImageField而不是FileField进行类型检查。另外,您可能希望规范化文件名扩展名(由于mimetype而不需要),例如

    def normalize_ext(image_field):
        try:
            from PIL import Image
        except ImportError:
            import Image
        ext = Image.open(image_field).format
        if hasattr(image_field, 'seek') and callable(image_field.seek):
           image_field.seek(0)
        ext = ext.lower()
        if ext == 'jpeg':
            ext = 'jpg'
        return '.' + ext
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看