线程建议使用multi_table_inheritance时,我遇到了与How to query abstract-class-based objects in Django?中类似的问题。我个人认为使用content_type在概念上更舒适(只是感觉更接近逻辑,至少对我来说是这样)
使用上一个链接中的示例,我只需添加一个StelarType作为
class StellarType(models.Model):
"""
Use ContentType so we have a single access to all types
"""
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')然后将其添加到抽象基模型中
class StellarObject(BaseModel):
title = models.CharField(max_length=255)
description = models.TextField()
slug = models.SlugField(blank=True, null=True)
stellartype = generic.GenericForeignKey(StellarType)
class Meta:
abstract = True要在StellarObject和StellarType之间同步,我们可以连接post_save signal,以便在每次创建行星或恒星时创建一个StellarType实例。这样,我就可以通过StellarType查询StellarObjects了。所以我想知道使用这种方法与使用multi_table_inheritance相比有什么好处和坏处?我认为两者都在数据库中创建了一个附加表。但是数据库性能如何呢?可用性/灵活性如何?感谢您的任何意见!
发布于 2012-10-19 16:40:50
对我来说,当你想要将一个对象与许多从根本上不属于同一“类型”的模型中的一个关联起来时,ContentType是一种方法。比如,如果你想在社交网络上对用户、页面和图片进行关键评论,但这三种模型之间没有合理的超类型共享。当然你可以创建一个"Commentable“超类型,但对我来说,这感觉更像是一个mixin,而不是一个基础类型,这三个东西都是从这个基础类型派生出来的。在ContentType出现之前,你别无选择,只能为这种关系发明超类型,如果你需要在同一个应用程序中多次这样做,这可能会变得非常丑陋,非常快(假设你也有事件,警报,消息等,每一个都可以应用于一组不同的模型)。
当您想要将属性附加到基本模型时,多表继承最有意义,这样它们将在所有从它扩展的具体模型中共享,这样您就可以获得多态行为。Commentable并不真正适合这个模型,因为所有的行为都可以放在Comment模型上,而Commentable对象上的情况就更少了。但如果你有不同类别的用户,他们分享了很多相同的行为,并且应该是可聚合的,那么它就更有意义了。
对我来说,多表继承的主要优点是一个更清晰的数据模型,具有隐式关系和继承,可以在Python端加以利用(尽管多态性仍然有点混乱,如here和here所见)。ContentType的主要优点是它更通用,并将辅助功能保留在模型之外,代价是稍微不那么原始的模式(模型上有许多“元”字段来定义这些关系)。对于您的示例,您仍然必须依赖于post_save,这在我看来也是不必要的混乱/神奇。
发布于 2015-12-24 08:32:52
很抱歉复活了旧线程。我认为这一切都归结为查找方向。无论是查找所有子类的某个FK (多表继承),还是将引用的类定义为内容类型并根据表引用和id (内容类型)查找它,都不会在性能上有很大差异-提示:它们都很糟糕。如果你想让你的应用程序易于扩展,我认为内容类型是一个很好的选择,也就是说,其他人可以添加新的内容类型来引用。如果您有时只需要在额外表中定义额外的列,则Multitable是好的。有时,合并所有子类型并只创建一个子类型可能也是一个好主意,其中有几个字段大部分时间都是空的。
https://stackoverflow.com/questions/12782847
复制相似问题