[Django]-Django – How to get self.id when saving a new object?

45👍

If it’s a new object, you need to save it first and then access self.id, because

"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."

Check django’s document https://docs.djangoproject.com/en/dev/ref/models/instances/

5👍

You might need to save this file/instance twice:

You can use a post_save signal on the model that looks for the created flag, and re-saves the instance updating the url (and moving/renaming the file as necessary), since the instance will now have an ID. Make sure you only do this conditioned on created, though, otherwise you will continuously loop in saving: saving kicks off a post-save signal, which does a save, which kicks off a post-save signal…

See https://docs.djangoproject.com/en/dev/ref/signals/#post-save

5👍

There is actually a way to trick this out.

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
👤Clark

2👍

I understand this is old but for anyone that stumbles across this in the future, here’s actually how you do it now in Django.

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

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

1👍

Note: You need to have the models.AutoField(primary_key=True) attribute set, otherwise the database will be updated with a new id but Django will not recognize it.

models.AutoField(primary_key=True)

-5👍

  q = Order.objects.values_list('id', flat=True).order_by('-id')[:1]
            if len(q):
                self.number = str(self.id) if self.id else str(int(q.get()) + 1)
            else:
                self.number = 1

Leave a comment