gpt4 book ai didi

Django:使用 ContentType 与 multi_table_inheritance

转载 作者:行者123 更新时间:2023-12-03 06:43:44 24 4
gpt4 key购买 nike

我遇到了类似的问题 How to query abstract-class-based objects in Django?该线程建议使用 multi_table_inheritance。我个人认为使用 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 之间进行同步,我们可以在每次创建 Planet 或 Star 时连接 post_save 信号来创建 StellarType 实例。这样我就可以通过StellarType查询StellarObjects了。所以我想知道使用这种方法相对于使用 multi_table_inheritance 的优点和缺点是什么?我认为两者都在数据库中创建了一个附加表。但是数据库性能如何呢?可用性/灵 active 怎么样?感谢您的任何意见!

最佳答案

对我来说,当您想要将一个对象与许多本质上不属于同一“类型”的模型之一关联时,ContentType 是一种可行的方法。就像您希望能够在社交网络上对用户、页面和图片添加评论一样,但这三个模型没有共享合理的父类(super class)型。当然,您可以创建一个“可评论”父类(super class)型,但对我来说,这感觉更像是一个 mixin,而不是这三个事物派生的基本类型。在 ContentType 出现之前,您别无选择,只能为这些类型的关系发明父类(super class)型,如果您需要在同一个应用程序中多次执行此操作(假设您还有事件、警报、消息等,每个都可以应用于不同的模型集)。

当您想要将属性附加到基本模型时,多表继承最有意义,这样它们将在从其扩展的所有具体模型中共享,以便您可以获得多态行为。 Commentable 并不真正适合这种模式,因为所有这些行为都可以放在 Comment 模型上,而不是放在 Commentable 对象上。但是,如果您有不同类别的用户,它们具有许多相同的行为并且应该是可聚合的,那么它就更有意义了。

对我来说,多表继承的主要优点是更清晰的数据模型,具有可以在Python端利用的隐式关系和继承(尽管多态性仍然有点困惑,如 herehere 所示)。 ContentType 的主要优点是它更通用,并且将辅助功能保留在模型之外,但代价是稍微不那么原始的模式(模型上有很多“元”字段来定义这些关系)。对于您的示例,您仍然必须依赖 post_save,这对我来说似乎也不必要地困惑/神奇。

关于Django:使用 ContentType 与 multi_table_inheritance,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12782847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com