Django建模,共同基础和一对多关系

时间:2015-07-20 08:06:49

标签: django model

我想创建两个相似的模型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中建模这些关系?

  • EDIT

1。使用ManyToManyField

根据arie的答案,我可以在另一边定义专辑 - 歌曲关系,只需注意名称(https://docs.djangoproject.com/en/dev/topics/db/models/#be-careful-with-related-name
另一个不同之处在于,我原来的问题有1-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。通用外键(基于马克答案)

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

我应该选择哪一个?
我应该在这些解决方案中挑选哪些问题?

2 个答案:

答案 0 :(得分:0)

如果从抽象类派生模型,最好直接向这些模型添加信息。 您可以尝试将Song类链接到AlbumA和AlbumB。

答案 1 :(得分:0)

您是否真的在谈论具有不同属性和数据库字段的不同类的相册?

如果您只关心处理不同专辑的歌曲,我认为不需要抽象基类,而是宁愿为我的模型建模:

class Song(models.Model):
    title = models.CharField(max_length=100)
    ...

class Album(models.Model):
    title = models.CharField(max_length=100)
    songs = models.ManyToManyField(Song)
    ...

或者,如果您确定在多个专辑(例如编辑或最佳专辑)的上下文中没有歌曲,您也可以这样做:

class Song(models.Model):
    title = models.CharField(max_length=100)
    album = models.ForeignKey(Album)
    ...

class Album(models.Model):
    title = models.CharField(max_length=100)
    ...

从您展示和描述的内容看不出任何需要GFK或继承。

这只是(简单)关系的问题。