【问题标题】:Django M2M relationships: Use just one intermediary table or one per entity pair?Django M2M 关系:只使用一个中间表还是每个实体对一个?
【发布时间】:2018-09-02 23:16:15
【问题描述】:

在创建多对多关系时,我们使用中间表。假设我使用以下实体 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

这也意味着,如果每个具体关系实例(行)上的 categorytag 字段之一为空,则将单个 taxonomy 实体用于两个关系可能有许多 NULL 字段。

问题:

什么会更好?保持中间表分开 (VideoCategory & VideoTag) 或将这些中间表合并为一个? (分类)


由于我缺乏数据库方面的经验,我不能说我是否遗漏了一些重要的东西。如果只使用一张中间表会在不久的将来出现问题或类似的事情......如果它就好了。

【问题讨论】:

  • 我猜我的第二个例子产生了模棱两可的相关字段。这样 django 就无法知道它应该使用哪个字段?这就是为什么我应该使用 through_fields 属性来指定它们。

标签: django database foreign-keys entity-relationship


【解决方案1】:

你必须使用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'))

【讨论】:

  • 如果我理解正确的话。这两行将位于Video 实体内。然后在属性through_fields=('video', 'category') 中,这两个字段将引用Taxonomy 实体中的videocategory 字段,其中models.ForeignKey(x)x 实体VideoCategory 对吗?
  • 任何人都可以编辑并添加一个示例来展示如何使用这些关系完成插入吗?
  • 我基于此提出了一个后续问题:stackoverflow.com/questions/49573288/…
猜你喜欢
  • 1970-01-01
  • 2020-08-10
  • 2014-09-02
  • 1970-01-01
  • 1970-01-01
  • 2021-04-14
  • 2020-02-15
  • 1970-01-01
  • 2022-01-21
相关资源
最近更新 更多