如何在保存实例之前获取 django 模型实例的 pk

Posted

技术标签:

【中文标题】如何在保存实例之前获取 django 模型实例的 pk【英文标题】:How to get pk of an instance of a django model before saving the instance 【发布时间】:2018-07-03 20:07:48 【问题描述】:

我正在尝试使用models.ImageField(upload_to=upload_location) 上传图片

def upload_location(instance,filename):
    print("%s/%s"%(instance.id,filename))
    return "%s/%s" %(instance.id,filename)

但它给予"GET /media/None/image_qacfEsv.jpg HTTP/1.1" 我尝试过使用 slug 字段,它运行良好,但 idpk 都不起作用 我想使用 obj ID 来命名图像的文件夹,但它在 id 属性中给出 none 这是我的文件

    def upload_location(instance,filename):
    print("%s/%s"%(instance.id,filename))
    return "%s/%s"%(instance.id,filename)

class Post(models.Model):
    draft = models.BooleanField(default=False)
    publish = models.DateField(auto_now=False,auto_now_add=False)
    user = models.ForeignKey(settings.AUTH_USER_MODEL,default=1)
    slug = models.SlugField(unique=True)
    title = models.CharField(max_length=120)
    image = models.ImageField(upload_to=upload_location,
                          null=True,blank=True,
                          width_field="width_field",
                          height_field="height_field")
    height_field = models.IntegerField(default=0)
    width_field = models.IntegerField(default=0)
    content = models.TextField()
    updated = models.DateTimeField(auto_now=True, auto_now_add=False)
    timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)

【问题讨论】:

保存对象前没有pk 那我现在该怎么办? 使用pk以外的东西。 【参考方案1】:

您无法在保存对象之前获得pk——事实上,检查对象是否具有pk 是检查它是否已保存的好方法。

因此,我建议在您的模型上添加一个 UUID 字段。比如:

import uuid

class Post(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    ...

uuid 字段将是唯一的,并且在您创建对象时可用,因此您可以在上传路径中使用它。

【讨论】:

【参考方案2】:

我遇到了类似的问题,我就是这样做的。

def upload_location(instance, filename):
    #return "%s/%s.%s" %(instance.id, instance.id, extension)
    if not instance.id:
        Model = instance.__class__
        new_id=None
        try:
            new_id = Model.objects.order_by("id").last().id
            if new_id:
                new_id += 1
            else:
                pass
        except:
            new_id=1
    else:
        new_id = instance.id
    return "%s/%s/%s" %(Model.__name__, new_id, filename)

【讨论】:

不错的方法顺便说一句,但我认为马克想出了一个最好的解决方案 这很聪明,但它看起来很容易受到竞争条件的影响——如果你同时有两个上传怎么办? 我同意,尽管这种情况非常罕见。另外,我将这段代码用于个人网站,所以没什么大不了的。 :) 感谢您的指点,我将避免使用此作为进一步参考。

以上是关于如何在保存实例之前获取 django 模型实例的 pk的主要内容,如果未能解决你的问题,请参考以下文章

如何运行保存在模型实例中的 Django 代码?

如何通过 HTML 中的 JavaScript 在 Django 中保存模型实例

Django:保存创建对象实例的用户

django 在父子模型类之间保存实例

如何设置模型实例以在Django中生成确认表单

风格 - 何时序列化 Django 模型实例:信号与模型的保存方法