上下文
我正在使用Django模型对数据进行建模。
主要模型是Article
。它包含实际内容。
然后每个Article
必须附加到一组文章。这些群组可能是Blog
,Category
,Portfolio
或Story
。每个Article
必须附加到一个{,1}。也就是说,无论是博客,类别还是故事。这些模型具有非常不同的领域和特征。
我想到了达到目标的三种方法(以及真正看起来错误的奖励)。
选项#1:通用外键
与django.contrib.contenttypes.fields.GenericForeignKey
一样。它看起来像这样:
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
模型。这看起来像这样:
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
创建一个附加表,然后Category
和Blog
将该表的隐式外键作为其主键。
旁注:我知道有a package可以自动记录这些结构。
选项#3:手动OneToOneFields
在数据库方面,它相当于选项#2。但在代码中,所有关系都是明确的:
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的继承魔法隐含的内容之外,我真的不明白这是什么意思。
加分:多列
它看起来很脏,所以我只是添加它作为奖励,但也可以直接在{{Category
,Blog
,...定义一个可为空的ForeignKey。 1}}模型。
因此...
......我无法真正决定这些。每种方法的优缺点是什么?有一些最佳做法吗?我错过了一个更好的方法吗?
如果重要,我会使用Django 1.8。
答案 0 :(得分:5)
似乎没有人建议分享那个。 我最终选择了多列选项,尽管说它看起来很难看。这一切都归结为三件事:
选项#1
选项#2
extra()
或自定义查询,但在某些时候没有理由再使用ORM。选项#3
<强>多列强>
select_related('category', 'blog', ...)
。Article
的表)并限制可能的类型数量,但我不太可能遇到这些问题。 希望它可以帮助任何有同样困境的人,并且仍然有兴趣听取其他意见。