Django M2M关系:只使用一个中间表或每个实体对一个?

时间:2018-03-24 10:58:39

标签: django database foreign-keys entity-relationship

创建多对多关系时,我们使用中间表。假设我使用以下实体videocategorytagVideoCategoryVideoTag来创建关系。

我假设许多标签/类别可以有很多视频,反之亦然。

我使用through关键字进行操作,因为如果需要,我希望以后可以使用额外的字段。

class Category(models.Model):
    category = models.CharField(max_length=50)

    def __str__(self):
        return self.category

class Tag(models.Model):
    tag = models.CharField(max_length=50)

    def __str__(self):
        return self.tag

class Video(models.Model):
    title = models.CharField(max_length=255)
    categories = models.ManyToManyField(Category, through='VideoCategory')
    tags = models.ManyToManyField(Tag, through='VideoTag')

    def __str__(self):
        return self.title

class VideoCategory(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    video = models.ForeignKey(Video, on_delete=models.CASCADE)

class VideoTag(models.Model):
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE)
    video = models.ForeignKey(Video, on_delete=models.CASCADE)

但我想知道是否有可能创建一个taxonomy实体并处理来自一个地方的类别和标签的关系。

class Category(models.Model):
    category = models.CharField(max_length=50)

    def __str__(self):
        return self.category

class Tag(models.Model):
    tag = models.CharField(max_length=50)

    def __str__(self):
        return self.tag

class Video(models.Model):
    title = models.CharField(max_length=255)
    categories = models.ManyToManyField(Category, through='Taxonomy')
    tags = models.ManyToManyField(Tag, through='Taxonomy')

    def __str__(self):
        return self.title

class Taxonomy(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True)
    tag = models.ForeignKey(Tag, on_delete=models.CASCADE, null=True)
    video = models.ForeignKey(Video, on_delete=models.CASCADE)

现在taxonomy实体会保留与视频相关的categorytag,反之亦然。

我已经包含了'null = True',以便能够与没有标签和标签但没有类别的类别创建关系。

如果我不使用它。我收到一个错误:

# sqlite3.IntegrityError: NOT NULL constraint failed: MyApp_taxonomy.category_id

这也意味着,如果其中一个taxonomyNULL字段在每个具体字段都为空,那么对于这两个关系使用该单个category实体可能会有多个tag字段关系实例(行)。

问题:

什么会更好?保持中间表分开(VideoCategory& VideoTag)或者将这些中间表连接成一个? (分类)

由于我缺乏数据库经验,我不知道我是否遗漏了一些重要内容。如果仅使用一个中间表进行此操作会在不久的将来出现问题或类似的问题...如果它没有问题。

1 个答案:

答案 0 :(得分:0)

您必须使用through_fields参数(doc):

class Video(models.Model):
    title = models.CharField(max_length=255)
    categories = models.ManyToManyField(Category, through='Taxonomy', through_fields=('video', 'category'))
    tags = models.ManyToManyField(Tag, through='Taxonomy', through_fields=('video', 'tag'))