我正在使用Django docs中的示例,并尝试在Django模型中创建一个计算字段。但是,这些字段不会显示在迁移中,然后当然也不会显示在数据库中。
这是我的模特。py
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()
def baby_boomer_status(self):
"Returns the person's baby-boomer status."
import datetime
if self.birth_date < datetime.date(1945, 8, 1):
return "Pre-boomer"
elif self.birth_date < datetime.date(1965, 1, 1):
return "Baby boomer"
else:
return "Post-boomer"
@property
def full_name(self):
"Returns the person's full name."
return '%s %s' % (self.first_name, self.last_name)
以及迁移文件:
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Person',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('first_name', models.CharField(max_length=50)),
('last_name', models.CharField(max_length=50)),
('birth_date', models.DateField()),
],
),
我误解了property属性吗?如果是这样,人们将如何获得计算字段以显示在数据库中?
答案 0 :(得分:3)
不是在数据库级别存储或计算那些“ 计算字段”。实际上,数据库根本不了解Python类(或Django模型)。
这些@property
实际上是在类级别定义的方法。这意味着如果有人查询some_person.full_name
,Python将在方法中执行计算,并返回结果。如果必要的属性之一发生了变化(可以说是“成分”),那么该属性的结果也可能会发生变化(再次获取时)。
另一个含义是,您不能不能 .filter(..)
使用此类属性。数据库 not 不知道full_name
的含义,因此您可以例如 not 指定Person.objects.filter(full_name__icontains='Bob')
,因为该字段及其对应的值不是存储在数据库中。
由于数据库与属性(或非列属性或方法)无关,因此这些属性不包括在迁移中。
如果您需要在数据库级别对其进行筛选(例如,对其进行过滤),则可以在查询集中执行.annotate(..)
。但是随后您将不得不将相应的逻辑编码到数据库表达式中。这可能很难,麻烦,甚至不可能(例如,如果该属性在文件系统上执行操作或查询Web服务,因为大多数数据库不支持此类操作)。