0

Lets say we have the following model:

class MyModel(models.Model):
    some_int = models.IntegerField()

I would like the value of MyModel.some_int to default to the value of MyModel.id.

For example, immediately after creating a new record in an empty version of MyModel, I could call MyModel.objects.get(id=1) and receive an object with id=1 and some_int=1. Is there a way to do this?

Edit: My current workaround is to set the default to 0, then go back and populate the value with the id of the created record, but that is messy.

For context: On an existing model similar to MyModel, I am being asked to add a new column that will render using the MyModel index obsolete as the reference point for the records in that model. Instead, I am adding a new, secondary column, that should store the values of the old IDs for previous records, and new values for future records. To do that though, I need to populate the column first.

Daniel Walker
  • 6,380
  • 5
  • 22
  • 45
Asa LeHolland
  • 372
  • 4
  • 12

1 Answers1

0

In short, check out post-save signals. Also check the generic guide to signals if you haven't used them before. Alternatively, overload the save() method.

To elaborate a bit, Django does allow using a callable as default for an IntegerField. However, because fields are defined as class variables - not instance variables - you can't access self and by extension self.id directly.

Therefore, you could grab the next id within such a callable using any of a number of methods (that would be a different question, one already answered several times on SO), and set your value to that ... but in that time, between reading that value and instantiating your MyModel at which point it is actually assigned an id, another MyModel could have been created and "stolen" that id, and now you have a row that has the incorrect some_int field that doesn't match its id.

Depending on your use case, this may not be a concern.

In general for any use case I don't believe there could possibly be a one-step solution. Setting the value after creation once it has been assigned an id is the only solution, "messy" though it is. The only question would be if Django has anything built in to assign a value after creation more clearly, a role that either overloading save() or using signals should fulfil.