Django Model Method or Calculation as Field in Database
You have to override the save
method of yout Model Person
and create unique_id
and age
field in the Model.
from dateutil.relativedelta import relativedelta
from datetime import datetime
class Person(model.Model)
unique_id = models.CharField(max_length=25)
age = models.IntegerField()
last_name = models.CharField(max_length=25)
birth_date = models.DateField()
city_of_birth = models.CharField(max_length=25)
@property
def get_unique_id(self):
a = self.last_name[:2].upper() #First 2 letters of last name
b = self.birth_date.strftime('%d') #Day of the month as string
c = self.city_of_birth[:2].upper() #First 2 letters of city
return a + b + c
@property
def get_age(self):
return relativedelta(self.birth_date.days, datetime.date.now()).years
def save(self, *args, **kwargs):
self.unique_id = self.get_unique_id
self.age = self.get_age
super(Person, self).save(*args, **kwargs)
UPDATE: Previously the self.get_unique_id
and self.get_age
were being called with '()' which is not required for class properties.
A model has a clean
method for this kind of thing:
This method should be used to provide custom model validation, and to modify attributes on your model if desired. For instance, you could use it to automatically provide a value for a field, or to do validation that requires access to more than a single field
So loose the property and add a field named 'unique_id' which should be a CharField. Rename get_id
to clean
and replace the return statement with:
self.unique_id = a + b + c
If you're certain this always generates a unique string, consider making this field the primary key. However, if this model is already migrated, you cannot name it id
, since Django has already created a field id
as an AutoField
for you, so it will take two migrations if you're set on the name 'id' (which you can squash later).