关于继承先前模型的意见

Posted

技术标签:

【中文标题】关于继承先前模型的意见【英文标题】:Opinion on inheriting a previous model 【发布时间】:2018-11-26 17:59:48 【问题描述】:

我正在查看我的代码,发现这两个模型有多个相似的字段。我想知道我的 ParentProfile 模型是否可以继承我的 User 模型以缩短代码并消除重叠。这是一个相当初学者的问题,希望其他人对此事发表意见。谢谢!

models.py

class User(AbstractBaseUser):
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    child_first_name = models.CharField(max_length=255)
    timestamp = models.DateTimeField(auto_now_add=True)
    student = models.BooleanField(default=False)
    parent = models.BooleanField(default=False)
    teacher = models.BooleanField(default=False)
    active = models.BooleanField(default=True) # can login
    staff = models.BooleanField(default=False) # staff user, not superuser
    admin = models.BooleanField(default=False) # superuser

    objects = UserManager()

    # takes email as username | removes email
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    def __str__(self):
        return self.email

    def has_perm(self, perm, onj=None):
        "Does the user have a specific permission?"
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app 'app_label'?"
        return True

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_admin(self):
        return self.admin

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

class ParentProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    child_first_name = models.CharField(max_length=255)
    timestamp = models.DateTimeField(auto_now_add=True)
    student = models.BooleanField(default=False)
    parent = models.BooleanField(default=False)
    teacher = models.BooleanField(default=False)
    active = models.BooleanField(default=True) # can login
    staff = models.BooleanField(default=False) # staff user, not superuser
    admin = models.BooleanField(default=False) # superuser

    objects = UserManager()

    # takes email as username | removes email
    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name', 'child_first_name']

    def __str__(self):
        return self.email

    def has_perm(self, perm, onj=None):
        "Does the user have a specific permission?"
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app 'app_label'?"
        return True

    @property
    def is_staff(self):
        return self.staff

    @property
    def is_admin(self):
        return self.admin

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

【问题讨论】:

一开始为什么会有两个相同的模型? 第二个模型有一个额外的字段。将继承第一个模型并简单地添加额外字段作为 child_first_name = models.CharField(max_length=255) 工作以及获得第一个模型的所有功能。或者我应该在我的表单中添加额外的字段并废弃整个模型 【参考方案1】:

您可以使用公共字段创建抽象模型并在两者中继承

class CommonFieldModel(models.Model):
    email = models.EmailField(max_length=255, unique=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)
    child_first_name = models.CharField(max_length=255)
    timestamp = models.DateTimeField(auto_now_add=True)
    student = models.BooleanField(default=False)
    parent = models.BooleanField(default=False)
    teacher = models.BooleanField(default=False)
    active = models.BooleanField(default=True) # can login
    staff = models.BooleanField(default=False) # staff user, not superuser
    admin = models.BooleanField(default=False) # superuser

    class Meta:
        abstract = True

正如Meta 类所定义的,它是一个抽象模型,Django 不会为此创建任何表。现在您可以在其他模型中继承此模型。例如。

class ParentProfile(CommonFieldModel):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
class User(CommonFieldModel, AbstractBaseUser):
    user = models.OneToOneField(User, on_delete=models.CASCADE)

【讨论】:

以上是关于关于继承先前模型的意见的主要内容,如果未能解决你的问题,请参考以下文章

django 抽象模型与常规继承

在 Django 中扩展用户对象:用户模型继承还是使用 UserProfile?

迁移复杂的核心数据模型

Java基础 | 关于面向对象三大特征与内存回收

继承性

探索C++对象模型