【发布时间】:2015-10-09 06:46:41
【问题描述】:
我想创建两个相似的模型 AlbumA 和 AlbumB。
他们都会有歌曲。
class AlbumBase(models.Model):
class Meta:
abstract=True
class Song(models.Model):
album = models.ForeignKey(AlbumBase) # problem here
class AlbumA(AlbumBase):
# with specific properties to A (DB fields)
pass
class AlbumB(AlbumBase):
# with specific properties to B (DB fields)
pass
我不认为Song 可以拥有abstract base class 的外键。
我应该如何在 django 中为这些关系建模?
- 编辑
1。使用多对多字段
根据arie的回答,我可以定义另一边的专辑-歌曲关系,只需注意名称(https://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name)
另一个区别是,我原来的问题有 1-Many 关系,而这个答案是 Many-Many。(我想要 1-Many,但可以和 M-M 一起生活。)
class AlbumBase(models.Model):
songs = models.ManyToManyField(Song, related_name="%(app_label)s_%(class)s_related")
class Meta:
abstract=True
class Song(models.Model):
pass
class AlbumA(AlbumBase):
pass
class AlbumB(AlbumBase):
pass
2。多表继承
或者我可以使用如下所示的多表继承。
class Album(models.Model):
pass # not abstract
class Song(models.Model):
album = models.ForeignKey(Album)
class AlbumA(Album):
pass
class AlbumB(Album):
pass
3。通用外键(基于 Mark 的回答)
class AlbumBase(models.Model):
class Meta:
abstract=True
class Song(models.Model):
content_type = models.ForeignKey(ContentType, db_index=True, related_name='+')
object_id = models.PositiveIntegerField(db_index=True)
album = generic.GenericForeignKey()
class AlbumA(AlbumBase):
pass
class AlbumB(AlbumBase):
pass
我应该选择哪一个?
在这些解决方案中,我应该问哪些问题?
【问题讨论】:
-
具体属性是什么?不同的数据库字段,还是python功能?
-
如果你够勇敢,你可以试试通用外键。大多数人对它们持负面评价或完全避免它们。但是,不幸的是抽象类不是很OO,只是为了减少代码重复。 docs.djangoproject.com/en/1.8/ref/contrib/contenttypes/…
-
@MarkGalloway:哦,我一直使用通用外键.. 不知道普遍的共识是反对使用它。您是否有任何链接(?在这里想不出更好的术语)来支持您对 GFK 的陈述?
-
多表继承的问题是你会产生额外的表连接。也许这对您来说不是一个明显的性能影响。很难说。
-
我刚刚听说要从其他开发人员 IRL 和这里避免使用它们。但是,我确实找到了这篇文章,所以也许我应该吃掉我的帽子。 stackoverflow.com/questions/14333460/…