Django M2M关系:仅使用一个中间表还是每个实体对使用一个? [英] Django M2M relationships: Use just one intermediary table or one per entity pair?

查看:55
本文介绍了Django M2M关系:仅使用一个中间表还是每个实体对使用一个?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在创建多对多关系时,我们使用中间表。可以说,我使用以下实体视频类别标签 VideoCategory VideoTag 创建关系。

When creating many to many relationships we use an intermediary table. Lets say I use the following entities video, category, tag, and VideoCategory, VideoTag to create the relations.

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

I'm assuming that many tags/categories can have many videos and vice-versa.

我使用通过关键字来做到这一点,因为希望以后能够使用更多字段。

And I do it with through keyword 'cause I want to be able to use extra fields in the future if I want.

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)

但我想知道是否有可能创建分类法实体,并从一个地方处理与类别和标签的关系。

But I was wondering if would be possible to create a taxonomy entity and handle the relationships with categories and tags from just one place.

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)

现在分类实体将保留类别标记与视频有关,反之亦然。

Now the taxonomy entity would hold the category and tag related to videos and vice-versa.

我添加了 null = True,以便能够与没有标签的类别和没有标签的类别建立关系。

I've included 'null=True' to be able to create relations with categories without tags and with tags but without categories.

如果我不使用它。我收到错误消息:

If I don't use it. I receive an error:

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

这也意味着对两个关系使用单个分类实体可能会有很多 NULL 字段,如果每个具体关系实例(行)上的这些类别 tag 字段之一为空)。

This also means that using that single taxonomy entity for the two relationships could have many NULL Fields if one of these category or tag fields are empty on every concrete relation instance (row).

有什么更好的选择?要将中间表分开(VideoCategory& VideoTag)还是将这些中间表合并为一个? (分类法)

What would be better ? To keep the intermediary tables separate (VideoCategory & VideoTag) Or to join these intermediary tables into just one ? (Taxonomy)

由于我缺乏数据库经验,所以我无法说自己是否错过了重要的事情。如果仅使用一个中间表就可能在不久的将来出现问题或类似问题……

Due to my lack of experience with databases I couldn't say if I'm missing something important. If doing it with just one intermediary table would give problems in near future or something like that... Of if it is just fine.

推荐答案

您必须使用 through_fields 参数(文档):

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'))

这篇关于Django M2M关系:仅使用一个中间表还是每个实体对使用一个?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆