这个问题是关于 Django 中的模型继承。
我读过的几乎所有内容(包括 Django 文档本身)都强烈建议执行 '抽象基类' 继承而不是 '多表' 遗产。
我同意推理,因此完全支持该建议。然而,Django 没有
似乎支持:
情况
例如,我有一些实现“抽象基类”继承模式的模型:
class Tool(models.Model):
name = models.CharField(max_length=30)
group = models.ManyToManyField(ToolGroup, blank=True) # Link to 'ToolGroup' MUST be placed on abstract class
attributes = models.ManyToManyField(ToolAttributeValue, blank=True) # Link to 'ToolAttributeValue' MUST be placed on abstract class
class Meta:
abstract = True # Almost everything I read strongly recommends against making this its own table
class HandheldTool(Tool):
electrical_safe = models.BooleanField(default=False)
class PowerTool(Tool):
compliance_expiry_date = models.DateTimeField()
class ConsumableTool(Tool):
combustible = models.BooleanField(default=False)
best_before = models.DateTimeField(null=True)
我也有一些与一般工具相关的分组和信息类:
# Grouping related structures
#
# ToolHierarchy > ToolGroup (n times) > Tool
#
# "Tool Boxes" > "Day Shift" > "Builders" > HandheldTool[Hammer]
# > HandheldTool[Screwdriver - SAFE]
# > PowerTool[Drill]
#
# > "Demo Team" > HandheldTool[Sledgehammer 1]
# > PowerTool[Jackhammer]
# > ConsumableTool[Dynamite]
#
# > "Night Shift" > "Rock Breakers" > HandheldTool[Hammer]
# > HandheldTool[Sledgehammer 2]
# > PowerTool[Rocksaw]
class ToolHierarchy(models.Model):
name = models.CharField(blank=True, max_length=30)
class ToolGroup(models.Model):
name = models.CharField(blank=True, max_length=30)
parent = models.ForeignKey('self', related_name='children', null=True, blank=True)
hierarchy = models.ForeignKey(ToolHierarchy, null=True, blank=True, related_name='top_level_tools')
# tools = models.ManyToManyField(Tool) # CANNOT MAKE LINK, as 'Tool' is abstract
# 'Extra-info' structures
#
# ToolAttribute > ToolAttributeValue > Tool
#
# 'Brand' > 'Stanley' > HandheldTool[Hammer]
# > HandheldTool[Sledgehammer 1]
# > 'ACME' > HandheldTool[Sledgehammer 2]
# > ConsumableTool[Dynamite]
#
# 'Supplier' > 'Bash Brothers' > HandheldTool[Hammer]
# > HandheldTool[Sledgehammer 1]
# > HandheldTool[Sledgehammer 2]
class ToolAttribute(models.Model):
name = models.CharField(max_length=30)
data_type = models.CharField(max_length=30) # e.g. "STRING", "INT", "DATE" "FLOAT" -- Actually done with enum
unit_of_measure = models.CharField(max_length=30, blank=True)
class ToolAttributeValue(models.Model):
attribute = models.ForeignKey(ToolAttribute)
value = models.CharField(blank=True, max_length=30)
# tool = models.ForeignKey(Tool) # CANNOT MAKE LINK, as 'Tool' is abstract
问题
理想情况下,这种继承模型将通过多态关系实现,但是 Django ORM 没有
支持它。这对于 SQLAlchemy 和其他 ORM(如 Hibernate)是可能的。
使用 Django ORM,因为
Tool
类是抽象的 I 不能创建如下链接:ToolAttributeValue.tool -> tool_obj
或 ToolGroup.tools -> [tool_obj_1, tool_obj_2]
. 相反,我被迫在抽象类上创建反向链接,尽管它建模略有不同!这会导致
ToolAttributeValue
上出现各种丑陋的情况。和 ToolGroup
对象,然后不再具有 .tools
属性,而是有 RelatedManager
每个子类型的字段。 IE。:tool_group_obj.handheldtool_set.all()
tool_group_obj.powertool_set.all()
...etc, for every subtype of Tool
这几乎破坏了抽象类的有用性。
问题
因此,考虑到这一点,我的问题是:
Tool
?如果是,那么我是否必须创建一个 *ToolGroup
每个子类的模型? 注意:我已阅读文档并测试了 https://github.com/chrisglass/django_polymorphic ,但它似乎不起作用
用于“抽象基类”继承(即仅适用于多表)。如果我确实选择了多表继承,那么
django-polymorphic 对我的问题的查询方面有好处,我想我的模型链接问题会消失。
注意:这是一个与 this one 类似的问题。 ,但提供了更多细节。
最佳答案
好吧,所以我想我会回答我自己的问题......
看起来是这样。尽管有一些地方建议不要使用“多表”继承 (listed here for example),但一些反对意见是:
Tool
?如果是,那么我是否必须创建一个 *ToolGroup
每个子类的模型? 不,似乎不是这样。
Tool
的两种用途我提出的界面有不同的需求:ToolGroup
/分层分组用例是保留继承的Tool
的好用例类(class)。如果您必须为每种类型的工具创建一组特定于类型的类,这将变得非常难看ToolAttribute
也为父类(super class)提供了一个很好的案例,除非您能够使用诸如 HSTORE 字段类型之类的东西(由 Postgres 提供,我不确定其他后端)。 This link给出了一个很好的概要,这可能是我在这里要做的(感谢@nigel222 对问题的研究!)。 现在这是一个无关紧要的问题。基本上他们不担心。
不是我能说的。
关于python - Django中的多态模型继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32606262/