Django - 如何在保存新对象时获取self.id?

时间:2013-01-09 12:10:13

标签: django django-models django-mptt

我的某个型号有问题。我正在上传一个图片,我想存储id(pk在数据库表中),但我需要知道Django可以访问self.id

models.py

class BicycleAdItemKind(MPTTModel):
    def url(self, filename):
        pdb.set_trace()

        url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (self.id, filename)
        return url

    def item_kind_image(self):
        return '<img align="middle" src="/media/%s" height="60px" />' % self.image
    item_kind_image.allow_tags = True     

    # Bicicleta completa, Componentes para bicicleta, Acessorios para ciclista
    n_item_kind      = models.CharField(max_length=50) 
    parent           = TreeForeignKey('self', null=True,
                                      blank=True, related_name='children')
    description      = models.TextField(null=True, blank=True)
    image            = models.ImageField(upload_to=url, null=True, blank=True)
    date_inserted    = models.DateTimeField(auto_now_add=True)
    date_last_update = models.DateTimeField(auto_now=True)

    def __unicode__(self):
        return self.n_item_kind

    class MPTTMeta:
        order_insertion_by = ['n_item_kind']

问题在于url()方法;我只能在更新对象时获得self.id,在创建新对象时我没有得到self.id。如何修改此模型,以便在创建新对象时获得self.id

使用当前代码,当我创建一个新对象时,我将得到一个类似的URL:

MultimediaData/HelpAdImages/ItemKind/None/somefile.jpg

我需要有类似的东西:

MultimediaData/HelpAdImages/ItemKind/35/somefile.jpg

任何线索?

7 个答案:

答案 0 :(得分:29)

如果是新对象,则需要先保存它,然后访问self.id,因为

"There's no way to tell what the value of an ID will be before you call save(), 
 because that value is calculated by your database, not by Django."

检查django的文档https://docs.djangoproject.com/en/dev/ref/models/instances/

答案 1 :(得分:4)

您可能需要保存此文件/实例两次:

您可以在模型上使用post_save信号查找已创建的标志,并重新保存更新URL的实例(并根据需要移动/重命名文件),因为实例现在将具有ID。确保你只在创建条件下进行此操作,否则你将继续循环保存:保存启动后保存信号,执行保存,启动保存后信号......

请参阅https://docs.djangoproject.com/en/dev/ref/signals/#post-save

答案 2 :(得分:2)

实际上有一种方法可以解决这个问题。

class Test(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=150)

    def __str__(self):
        return self.name

    def update_model(self):
        # You now have both access to self.id and self.name
    
        test_id = Test.objects.get(name=self.name).id
        print(test_id)
    
        # Do some stuff, update your model...
        Test.objects.filter(id=test_id).update(name='New Name')
        

    def save(self, *args, **kwargs):
        super(Test, self).save(*args, **kwargs)
        self.update_model() # Call the function

答案 3 :(得分:1)

注意:您需要设置models.AutoField(primary_key=True)属性,否则数据库将使用新ID进行更新,但Django无法识别它。

models.AutoField(primary_key=True)

答案 4 :(得分:0)

我知道这很老了,但是对于以后偶然遇到这个问题的人,实际上是您现在在Django中的处理方法。

def url(instance, filename):
        pdb.set_trace()

        url = "MultimediaData/HelpAdImages/ItemKind/%s/%s" % (instance.id, filename)
        return url

答案 5 :(得分:-3)

我知道这是一个旧的,但我认为这对某人有用,似乎到目前为止工作正常。

<强> Views.py

    #Queries model and appends id's to list
    try:
        qs = YourModel.objects.all()
        qslist = []

        for item in qs:
            qslist.append(item.id)

        newid = int(max(qslist) + 1)
    #If no entries are found, assume this is the first entry.
    except:
        newid = 1

但是,我不确定这对大型数据库的表现如何。

答案 6 :(得分:-4)

var showCurrentMonth = function() {
        var getMonth = new Date().getMonth();
        console.log(getMonth);
        var month = ["january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"];

        var actualMonth = "";
        for (var i = 0; i < month.length; i++) {
            var checkMonth = month[i];

            if (getMonth == i) {
                actualMonth = checkMonth;
            }
        }
        console.log(actualMonth);
    };
    window.addEventListener('DOMContentLoaded', showCurrentMonth, false);
相关问题