基类上的可选字段,但在Django中的子类上是必填字段

时间:2019-03-14 05:27:40

标签: django django-models

我想知道是否有可能有2个类(base = person和child = user),其中我有一个属性(电子邮件)可以为空,但必须为子类设置

class Person(models.Model):
    name = models.CharField(max_length=60, )
    identification = models.CharField(max_length=20, unique=True)
    email = models.CharField(max_length=60, null=True) #<~~~~ Email can be null

    def __str__():
        return self.name

class User(Person):
    email = models.CharField(max_length=60, ) #<~~~~ Email CAN'T be null

如果我这样离开,则会出现此错误:

django.core.exceptions.FieldError: Local field 'email' in class 'User' clashes with field of the same name from base class 'Person'.

谢谢。

3 个答案:

答案 0 :(得分:0)

您可以覆盖字段属性。 保持人员email字段不变。 将用户email字段更改为

email = models.CharField(max_length=60, null=False)

答案 1 :(得分:0)

您必须添加class Meta: abstract = True(注意:不要在字符字段中使用null,而应使用blank。):: 即:

class Human(models.Model):
    name = models.CharField(max_length=60, )
    identification = models.CharField(max_length=20, unique=True)
    email = models.CharField(max_length=60, blank=True)
    class Meta:
        abstract = True

class Person(Human):    
    def __str__():
        return self.name

class User(Human):
    email = models.CharField(max_length=60 ) #<~~~~ Email CAN'T be null

答案 2 :(得分:0)

在进行multi model inheritance时,子级将为父级模型创建一个OneToOne relation,因此在子级模型中,父级的字段(在您的情况下为email)不存在(数据库明智的)。因此,采用这种方法,您不能将电子邮件字段设为不为空

因此,最好声明一个基本抽象类。然后从那里继承PersonUser模型。例如:

class Base(models.Model):
    name = models.CharField(max_length=60, )
    identification = models.CharField(max_length=20, unique=True)
    email = models.CharField(max_length=60, blank=True, null=True, default=None)

    class Meta:
        abstract = True

class Person(Base):    

     def __str__(self):
        return self.name

class User(Base):
    email = models.CharField(max_length=60)  # <-- Override the base email field

    def __str__(self):
        return self.name