[英]Django Model Method or Calculation as Field in Database
Using Django ~=1.11 and Python 3.6使用 Django ~=1.11 和 Python 3.6
I need to store 'calculated' variables as fields in the Django model database.我需要将“计算”变量存储为 Django 模型数据库中的字段。
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.我正在使用这些字段创建唯一 ID。 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.我想对 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.所以我想将 UniqueID 和 Age 变量存储在数据库中,作为 Person 模型中的字段。 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 .问题是我需要在self.unique_id=self.get_unique_id之后删除save() 部分中的括号。 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
You have to override the save
method of yout Model Person
and create unique_id
and age
field in the Model.您必须覆盖 Model Person
的save
方法并在 Model 中创建unique_id
和age
字段。
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.更新:以前self.get_unique_id
和self.get_age
是用 '()' 调用的,这不是类属性所必需的。
A model has a clean
method for this kind of thing:模型对这种事情有一个clean
方法:
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.所以松开属性并添加一个名为“unique_id”的字段,它应该是一个 CharField。 Rename get_id
to clean
and replace the return statement with:重命名get_id
以clean
并将返回语句替换为:
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).但是,如果此模型已经迁移,则不能将其命名为id
,因为 Django 已经为您创建了一个字段id
作为AutoField
,因此如果您设置了名称 'id'(您可以稍后南瓜)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.