Django,Python继承:从超类中排除一些字段

Posted

技术标签:

【中文标题】Django,Python继承:从超类中排除一些字段【英文标题】:Django, Python inheritance: Exclude some fields from superclass 【发布时间】:2017-08-09 04:15:27 【问题描述】:

我在 Employee 和 Manager 类之间有继承。员工 - 超类,经理 - 子类。

class Employee(models.Model):
    ###
    name = models.CharField(max_length=50, null=False)
    address = models.CharField(max_length=50, null=False)
    ###

class Manager(Employee):
    department = models.CharField(max_length=50)
    ###
    here I don't want the 'name' and 'address' fields of Employee class.
    (I want other fields of Employee and department field of this class to be stored in 
    Manager table in database)
    ###

如何做到这一点。提前致谢。

【问题讨论】:

即使这是可能的,这将使Manager 没有名字。你确定要那个吗? 在其他语言中,您将创建 Employee private 字段,而不是 publicprotected 为什么不用foreingkey? 是的,我绝对希望将这些字段从 Manager 中完全删除 把你想要的字段放在一个abstract模型中,让Employee和Manager都继承?但实际上,我觉得这里根本不应该使用继承。 【参考方案1】:

您可以使用 2 个下划线 (__) 在 python 类中创建私有变量,查看this 示例了解更多信息。

但是他们会将这些值存储在子对象中,因为在 Python 中没有私有或受保护的东西。

但另一种方法也适用于 Django。在 Django 中,模型字段的存储取决于它们的值(CharFieldDateField 等),但如果您将项目值设为None 或任何其他静态值(例如"string"),那应该可以解决您的问题:

class Manager(Employee):
  name = None
  address = None
  # other_stuffs.

在该示例中,Manager 不应在数据库中包含名称和地址列,当您尝试访问它们时,您将获得None。如果你想得到AttributeError(当对象没有请求密钥时Django会提出这个问题),那么你还可以添加属性:

class Manager(Employee):
  name = None
  @property
  def name(self):
    raise AttributeError("'Manager' object has no attribute 'name'")

【讨论】:

【参考方案2】:

我会使用 3 个类:

class BaseEmployee(models.Model):
    # All your common fields

class Employee(BaseEmployee):
    name = models.CharField(max_length=50, null=False)
    address = models.CharField(max_length=50, null=False)

class Manager(BaseEmployee):
    department = models.CharField(max_length=50)

我认为这实现了你想要的。

【讨论】:

以上是关于Django,Python继承:从超类中排除一些字段的主要内容,如果未能解决你的问题,请参考以下文章

Python子类方法从超类方法继承装饰器

无法从超类访问 Django 模型的子类

子类没有正确地从超类继承结构[重复]

从超类中获取子类的名称

如何从超类中检测对象

子类是不是从超类继承私有实例变量