【问题标题】:Django model is inheriting all super model Fields, except for IntegerFieldDjango 模型继承了所有超模型字段,除了 IntegerField
【发布时间】:2019-08-08 15:53:36
【问题描述】:

我遇到了一个奇怪的问题,我有一个模型的层次结构,一个抽象的用户类:

class User(AbstractBaseUser):
    user_name = models.CharField(max_length=32, unique=True)
    email = models.EmailField(max_length=255, unique=True, null=True)
    phone = PhoneNumberField()
    access_token = models.CharField(max_length=255, unique=True, null=True)
    notifications_token = models.CharField(max_length=255, unique=True, null=True)
    photo = models.ImageField(null=True)
    person_in_contact = models.CharField(max_length=32, null=True)
    active = models.BooleanField(default=False)
    confirmedEmail = models.BooleanField(default=False)
    confirmedPhone = models.BooleanField(default=False)
    completedProfile = models.BooleanField(default=False)
    visible = models.BooleanField(default=True)

    @property
    def is_active(self):
        return self.active

    # def __str__(self):
    #     return "Client : " + self.user_name + " Email:" + self.email

    def get_email(self):
        return self.email

    USERNAME_FIELD = 'user_name'

    REQUIRED_FIELDS = ['user_name', 'phone', 'password']

    class Meta:
        abstract = True

然后是继承自该类的个人类和公司(这个没有问题)类:

class Person(User):
    GENDER = (('F', 'FEMALE'), ('M', 'MALE'))

    name = models.CharField(max_length=50, null=True)
    surname = models.CharField(max_length=50, null=True)
    adress = models.CharField(max_length=255, null=True)

    birth_date = models.DateField(null=True)
    gender = models.CharField(max_length=1, choices=GENDER, null=True)
    age = models.IntegerField(null=True)

    def age(self):
        today = date.today()
        return today.year - self.birth_date.year

    # def __str__(self):
    #     return super().__str__() + " Name : " + self.name

    class Meta:
        abstract = True

如您所见,IntegerField() 的唯一字段是年龄字段。 现在我有一个继承自 person 类的 Traveler 和 Driver 类, 问题是年龄字段,不显示在数据库中,除非我在其中一个类中覆盖它,这就是我所做的,我在旅行者中覆盖它,所以它出现在数据库中,但没有在司机,所以没有显示。 旅行者:

class Traveller(Person):
    photo = models.ImageField(null=True, upload_to='travellers/profile_pictures')
    age = models.IntegerField(null=True)

    class Meta:
        verbose_name_plural = 'Travellers'

司机:

class Driver(Person):
    rating = models.DecimalField(default=0, decimal_places=1, max_digits=3)
    driving_license = models.CharField(max_length=50, null=True)
    insurance_number = models.CharField(max_length=50, null=True)
    company = models.ForeignKey(TransportCompany, on_delete=models.DO_NOTHING, null=True)
    photo = models.ImageField(null=True, upload_to='drivers/profile_pictures')

我需要知道如何解决这个问题,或者是什么问题,感谢任何帮助。

【问题讨论】:

  • 您确实点头在此处添加了age 字段。由于您定义了一个具有相同名称的函数,因此该属性被“覆盖”。请重命名两者之一。
  • 请注意,年龄还不是出生年份与当年之间的差异。
  • @WillemVanOnsem 谢谢老兄,我修正了方法名称,它解决了这个问题,但我没有明白你的意思“年龄不是出生年份和当前年份之间的差异年”...那是怎么计算的呢?
  • 如果你有出生日期,为什么要首先将年龄存储在数据库中?永远不要存储可以从其他字段计算的属性。如果我是你,我会完全删除 age 字段并只保留 def age(self) 方法(将其更改为 @property,甚至更好)以返回计算值。
  • @dirkgoten:我认为是因为一个人可能会决定指定他/她的年龄,而不是他/她的出生日期。

标签: django django-models django-inheritance


【解决方案1】:

发生这种情况的原因是您的age 字段与age 函数同名。因此,age = ... 字段被 Python 忽略,而使用 age 函数,因为这是您最后一次定义 age 变量。

出于同样的原因,age 字段会在子类中弹出:您在那里定义了一个 age 变量,它优先于“继承的”年龄方法。

您应该重命名两者之一。例如:

class Person(User):
    GENDER = (('F', 'FEMALE'), ('M', 'MALE'))

    name = models.CharField(max_length=50, null=True)
    surname = models.CharField(max_length=50, null=True)
    adress = models.CharField(max_length=255, null=True)

    birth_date = models.DateField(null=True)
    gender = models.CharField(max_length=1, choices=GENDER, null=True)
    _age = models.IntegerField(null=True)

    def age(self):
        today = date.today()
        bod = self.birth_date
        before_dob = (today.month, today.day) < (bod.month, bod.day)
        return today.year - self.birth_date.year - before_dob

    class Meta:
        abstract = True

请注意,age 的计算并不完全准确:如果我们在当年的生日之前,则需要从年龄中减去一个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多