Django计算字段未出现在迁移中

时间:2018-07-19 13:07:12

标签: python django django-models

我正在使用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属性吗?如果是这样,人们将如何获得计算字段以显示在数据库中?

1 个答案:

答案 0 :(得分:3)

不是在数据库级别存储或计算那些“ 计算字段”。实际上,数据库根本不了解Python类(或Django模型)。

这些@property实际上是在类级别定义的方法。这意味着如果有人查询some_person.full_name,Python将在方法中执行计算,并返回结果。如果必要的属性之一发生了变化(可以说是“成分”),那么该属性的结果也可能会发生变化(再次获取时)。

另一个含义是,您不能不能 .filter(..)使用此类属性。数据库 not 不知道full_name的含义,因此您可以例如 not 指定Person.objects.filter(full_name__icontains='Bob'),因为该字段及其对应的值不是存储在数据库中。

由于数据库与属性(或非列属性或方法)无关,因此这些属性不包括在迁移中。

如果您需要在数据库级别对其进行筛选(例如,对其进行过滤),则可以在查询集中执行.annotate(..)。但是随后您将不得不将相应的逻辑编码到数据库表达式中。这可能很难,麻烦,甚至不可能(例如,如果该属性在文件系统上执行操作或查询Web服务,因为大多数数据库不支持此类操作)。