Search code examples
pythondjangodjango-rest-frameworkdjango-signals

Access primary key/id value during creation of a Django record


For my model I use default auto-incremented PrimaryKey/id field. I also have a field called serialNumber which according to design should reference id and generate it's own value based on id value. For example if id is 1234 then serialNumber field should be a string '00001234'.

class MyModel(models.Model):
    ...
    serialNumber = models.TextField(max_length=8)
    ...

I have no trouble updating serialNumber after the creation of record in DB, but my specific case requires serialNumber to be set together with object initial creation because right after it I return the record via REST API.

I tried using signals, but pre_save returns None

@receiver(pre_save, sender=MyModel)
def my_pre_save(sender, instance, **kwargs):
    print(instance.id)

On the other hand if I do:

@receiver(post_save, sender=MyModel)
def my_post_save(sender, instance, **kwargs):
    print(instance.id)

I receive the value for id but it's too late because right after .save() my REST API returns response with created object and I don't want to add code that manages serialNumber to serializer.

Overriding .save() method for MyModel didn't work either:

    def save(self, *args, **kwargs):
        print(self.id)
        super(MyModel, self).save(*args, **kwargs)

Id field still returns None.

Anyone has an idea how to access id value during initial creation of a record?


Solution

  • Well there is no way you can access the ID before saving it. ID will be generated by database so you have to call save method so django sends the data to database and then you'll have your ID

    This has been explained in django documentations too:

    Auto-incrementing primary keys

    If you really need to access the ID which is a unique identifier, you can create one manually.

    You can add a field called my_id and then give it a unique value before saving the data (you just need to check if that value already exist or not and if it does, then just create another one). This way you'll be able to get a unique ID which you'll be able to find that row with in future.