创建多对多关系时,我们使用中间表。假设我使用以下实体video
,category
,tag
和VideoCategory
,VideoTag
来创建关系。
我假设许多标签/类别可以有很多视频,反之亦然。
我使用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
实体会保留与视频相关的category
和tag
,反之亦然。
我已经包含了'null = True',以便能够与没有标签和标签但没有类别的类别创建关系。
如果我不使用它。我收到一个错误:
# sqlite3.IntegrityError: NOT NULL constraint failed: MyApp_taxonomy.category_id
这也意味着,如果其中一个taxonomy
或NULL
字段在每个具体字段都为空,那么对于这两个关系使用该单个category
实体可能会有多个tag
字段关系实例(行)。
什么会更好?保持中间表分开(VideoCategory& VideoTag)或者将这些中间表连接成一个? (分类)
由于我缺乏数据库经验,我不知道我是否遗漏了一些重要内容。如果仅使用一个中间表进行此操作会在不久的将来出现问题或类似的问题...如果它没有问题。
答案 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'))