本文介绍了使用当前模型 ID 上传 Django 管理文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用默认的 Django 管理员创建一个简单的照片库.我想为每个画廊保存一张示例照片,但我不想保留文件名.而不是文件名,我想保存模型的 id (N.jpg).但是第一次我想保存id不存在的对象.我怎么知道模型中的下一个自动增量,或者在使用 super.save 上传之前以某种方式保存模型数据,并在 self.id 存在后上传文件?有没有很酷的解决方案?

I'm trying to create a simple photo gallery with the default Django admin. I'd like to save a sample photo for each gallery, but I don't want to keep the filname. Instead of the filename, I'd like to save the id of the model (N.jpg). But the first time I want to save the object the id does not exist. How could I know the next auto increment in the model, or somehow save the model data before the upload with super.save and after upload the file when self.id is exists? Is there a cool solution?

像这样:

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)

也许将文件名存储在不同的字段中.

And maybe store the filename in a different field.

推荐答案

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

The image file gets saved before Gallery instance. So you have to split the saving to two phases by using signals w/ Gallery instance itself carrying the state:

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 看起来像

The upload_path_handler looks like

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,这是不必要的),如

I suggest using ImageField instead of FileField for type-checking if the field is for image uploading only. Also, you may want to normalize filename extension (which is unnecessary because of the mimetype) like

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

这篇关于使用当前模型 ID 上传 Django 管理文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 14:46