django instance.id =上传图片时无

时间:2017-01-02 14:02:30

标签: python django django-models

通过管理页面上传图片时,

instance.id正在返回None。我们的想法是将每个Residence的所有图像上传到不同的文件夹。这是我的代码:

models.py

from django.db import models
import os

def get_image_path(instance, filename):
    return os.path.join('photos', "residence_%s" % instance.id, filename)


# Create your models here.
class Residence(models.Model):
    big_image = models.ImageField("Main Image",upload_to=get_image_path)
    small_images = models.ImageField("Small Images",upload_to=get_image_path, blank=True, null=True)

settings.py

MEDIA_URL = '/media/'

编辑:如果我在添加模型后修改图像,它会起作用。

3 个答案:

答案 0 :(得分:4)

除非您实施自定义动态文件上传字段,否则无法以此方式执行此操作。由于您尝试访问instance.id,但instance尚未保存,并且没有id

这里有一些资源可以帮助您实现目标:

答案 1 :(得分:1)

另一个解决此问题的好方法是需要更少的代码,让你的模型使用UUID作为主键,而不是数据库生成的id。这意味着在第一次保存模型时UUID已经知道,并且可以与任何from django.db import models import uuid import os def get_image_path(instance, filename): return os.path.join('photos', "residence_%s" % str(instance.id), filename) # Create your models here. class Residence(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False) big_image = models.ImageField("Main Image",upload_to=get_image_path) small_images = models.ImageField("Small Images",upload_to=get_image_path, blank=True, null=True) 回调一起使用。

因此,对于原始示例,您可以执行类似这样的操作

{{1}}

有关详细信息,请参阅Django's UUIDField reference

答案 2 :(得分:1)

如果您没有在update_to上指定ImageField,则可以上传到媒体根目录,然后使用post_save信号更改路径。

@receiver(post_save, sender=Product)
def update_file_path(instance, created, **kwargs):
    if created:
        initial_path = instance.image.path
        new_path = settings.MEDIA_ROOT + f'/product_{instance.id}/{instance.image.name}'
        os.makedirs(os.path.dirname(new_path), exist_ok=True)
        os.rename(initial_path, new_path)
        instance.image = new_path
        instance.save()