Access primary key/id values during Django record creation
For my model, I use the default auto-incrementing PrimaryKey/id
field. I also have a field called serialNumber
which, by design, should reference id and generate its own value based on
the id
value.
For example, if the id
is 1234
, then the serialNumber
field should be a string ‘00001234'
.
class MyModel(models. Model):
...
serialNumber = models. TextField(max_length=8)
...
I
have no problem updating serialNumber after creating a record in the database, but my specific situation requires serialNumber
to be set along with the initial creation of the object, because after it I return the record via the REST API
.
I tried using signals
, but pre_save returned 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
received the value for id, but it was too late because after .save()
my REST API
returned a response with the created object, and I didn’t want to add code to manage serialNumber
to the
serializer.
Overriding the .save()
method for MyModel
also doesn’t work:
def save(self, *args, **kwargs):
print(self.id)
super(MyModel, self).save(*args, **kwargs)
The Id
field still returns None
.
Does anyone know how to access the id
value during initial record creation?
Solution
Well, you can’t access the ID before saving it.
The ID will be generated by the database, so you have to call the save
method so that django sends the data to the database, and then you will have your ID
This is also explained in the Django documentation:
Auto-incrementing primary keys
If you do need access to a uniquely identified ID, you can create one manually.
You can add a field named my_id
and then give it a unique value before saving the data (you just need to check if the value already exists, and if it does, just create another one). In this way, you will be able to get a unique ID with which you can find the row in the future.