首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用GenericForeignKey与多表继承与OneToOneField的优缺点是什么?

使用GenericForeignKey与多表继承与OneToOneField的优缺点是什么?
EN

Stack Overflow用户
提问于 2015-05-31 19:56:28
回答 1查看 1.5K关注 0票数 12

上下文

我正在使用Django模型对数据进行建模。主要型号是Article。它保存了实际内容。

然后,每个Article必须附加到一组文章。这些组可能是BlogCategoryPortfolioStory。每个Article必须连接到一个,而正是其中之一。也就是说,一个博客,一个类别,或者一个故事。这些模型有非常不同的领域和特点。

我想出了三种方法来达到这个目标(还有一种奖励--一种看起来确实不对的方法)。

选项1:通用外键

就像在django.contrib.contenttypes.fields.GenericForeignKey一样。看起来是这样的:

代码语言:javascript
运行
复制
class Category(Model):
    # some fields

class Blog(Model):
    # some fields

class Article(Model):
    group_type = ForeignKey(ContentType)
    group_id = PositiveIntegerField()
    group = GenericForeignKey('group_type', 'group_id')
    # some fields

在数据库方面,这意味着模型之间实际上不存在任何关系,它们由Django强制执行。

选项2:多表继承

使项目组全部继承自ArticleGroup模型。这个应该是这样的:

代码语言:javascript
运行
复制
class ArticleGroup(Model):
    group_type = ForeignKey(ContentType)

class Category(ArticleGroup):
    # some fields

class Blog(ArticleGroup):
    # some fields

class Article(Model):
    group = ForeignKey(ArticleGroup)
    # some fields

在数据库端,这将为ArticleGroup创建一个附加表,然后CategoryBlog将该表的隐式外键作为其主键。

Sidenote:我知道有https://github.com/chrisglass/django_polymorphic可以自动化这些结构的簿记。

选项3:手动OneToOneFields

在数据库方面,它等同于选项2。但是在代码中,所有关系都是显式的:

代码语言:javascript
运行
复制
class ArticleGroup(Model):
    group_type = ForeignKey(ContentType)

class Category(Model):
    id = OneToOneField(ArticleGroup, primary_key=True)
    # some fields

class Blog(Model):
    id = OneToOneField(ArticleGroup, primary_key=True)
    # some fields

class Article(Model):
    group = ForeignKey(ArticleGroup)
    # some fields

我不太明白这有什么意义,除了明确Django的继承魔术的含义之外。

奖金:多色

它看起来很脏,所以我只是把它作为一个奖励,但它也可以定义一个可空的ForeignKey到每个CategoryBlog,.直接在Article模型上。

所以.

...I不能在这两者之间做出真正的决定。每种方法的优缺点是什么?有什么最佳做法吗?我错过了更好的方法吗?

如果这有关系,我使用Django 1.8。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-07-06 15:15:07

看来没人能在那件事上分享意见。我最终选择了多色选择,尽管我说过它看起来很难看。这一切归结为三件事:

  • 基于数据库的可执行性。
  • Django ORM与不同构造的工作方式。
  • 我自己的需求(即收集组中的查询以获取项目列表,以及获取组所需项的单个查询)。

选项#1

  • 无法在数据库级别强制执行。
  • 在查询上可能是有效的,因为它的构造方式不属于通常的泛型外键陷阱。当项目是泛型的,而不是集合时,就会发生这种情况。
  • 但是,由于ORM如何处理GFK,所以不可能使用自定义管理器,因为我的文章是用姜戈-hvad翻译的。

选项2

  • 可以在数据库级别强制执行。
  • 可能有些效率,但会遇到ORM限制,这显然不是围绕这种使用构建的。除非我经常使用extra()或自定义查询,但是在某些时候没有理由再使用ORM了。

选项#3

  • 实际上,它比#2要好一些,因为使用ORM时,通过显式处理可以更容易地优化查询。

多色门

  • 结果并不是那么糟糕。它可以在数据库级别强制执行(FK约束加上手动检查,以确保其中一个列为非空)。
  • 简单高效。一个直观的查询就可以完成这个任务:select_related('category', 'blog', ...)
  • 虽然它确实存在很难扩展的问题(任何新类型也需要修改Article的表)并限制可能的类型数量,但我不太可能遇到这些问题。

希望它能帮助那些同样进退两难的人,并且仍然有兴趣听取其他人的意见。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30562039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档