Using Django ~=1.11 and Python 3.6
I need to store 'calculated' variables as fields in the Django model database.
Here's a model:
from django.db import models
from datetime import date
class Person(model.Model)
"Last Name"
last_name = models.CharField(max_length=25)
"Birthday"
birth_date = models.DateField()
"City of birth"
city_of_birth = models.CharField(max_length=25)
I am creating a Unique ID using these fields. Specifically, I'm conjoining parts of each field into one string variable (details below). I was able to get this to work as a Property but I don't know how to store a calculated field in the database.
"Unique ID"
def get_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
unique_id = property(get_id)
I want to do a similar thing with Age. Here's what I have as a calculation:
"Age calculated from Birth Date"
def get_age(self):
return int((datetime.date.now() - self.birth_date.days) / 365.25)
age = property(get_age)
So I'd like to store the UniqueID and Age variables in the database, as fields in the Person model. What is the best practice when doing these? Do I need to initialize the fields first, then do some sort of update query to these?
Note: It is my understanding that the current code using 'property' works for rendering in the view, but it is not stored in the database.
Thanks in advance! Please help me improve what I already have.
UPDATE: Here is code that worked for me. The problem was that I needed to drop the parentheses in the save() section, after self.unique_id=self.get_unique_id . It has been suggested to drop age from the database, and leave it as a property.
class Person(models.Model):
unique_id = models.CharField(max_length=6, blank=True)
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 age(self):
return relativedelta(self.birth_date.days, datetime.date.now()).years
def save(self, *args, **kwarg):
self.unique_id = self.get_unique_id
super(Person, self).save(*args, **kwarg)
def __str__(self):
return self.unique_id
Fields in Django are the data types to store a particular type of data. For example, to store an integer, IntegerField would be used. These fields have in-built validation for a particular data type, that is you can not store “abc” in an IntegerField.
get_queryset() method by appending your calculated field. The calculated field is created using . annotate() . Finally, you set the objects Manager in your Model to your new Manager .
A Django model is the built-in feature that Django uses to create tables, their fields, and various constraints. In short, Django Models is the SQL of Database one uses with Django.
Mine is simpler to implement, and you can pass a list, dict, or anything that can be converted into json. In Django 1.10 and above, there's a new ArrayField field you can use.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With