Django 多对多真的有必要吗?

Mar*_*000 3 django python-3.x

去年我一直在学习使用 Django,而 Python 不是我的母语编程语言。通常,当我想创建多对多关系时,我会创建 3 个表,其中一个包含指向其他两个表中的每一个的两个外键。出于这个原因,我发现 Django manytomany 字段非常不自然。这个多对多字段是否会在数据库中创建第三个表来存储关系?如果是这种情况,则使用多对多字段将阻止类结构直接表示表结构。

我想知道的是,是否有理由我应该使用这个 manytomany 字段,或者我可以使用 3 个类来表示多对多关系吗?

谢谢

标记

Wil*_*sem 5

我将创建 3 个表,其中一个包含其他两个表中每个表的两个外键。出于这个原因,我发现 Django manytomany 字段非常不自然。

正是Django 在幕后所做的事情。如果您检查数据库,您将看到一个连接表[wiki]。Django 只是在后台执行此操作。它只是其作为一个字段呈现在前台。正如你可以在看到数据库表示ManyToManyField

在幕后,Django创建了一个中间连接表来表示多对多关系。默认情况下,此表名称是使用多对多字段的名称和包含它的模型的表名称生成的。由于某些数据库不支持超过一定长度的表名,这些表名将被自动截断并使用唯一性哈希,例如author_books_9cdf. 您可以使用该db_table选项手动提供连接表的名称。

您甚至可以通过在两者之间显式定义模型并在through=…参数 [Django-doc] 中指定它来向此联结表添加额外的字段。例如:

class Category(models.Model):
    name = models.CharField(
        max_length=128,
        unique=True
    )

class Item(models.Model):
    name = models.CharField(
        max_length=128,
        unique=True
    )
    categories = models.ManyToManyField(
        Category,
        through='ItemCategory'
        related_name='items'
    )

class ItemCategory(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE)
    item = models.ForeignKey(Item, on_delete=models.CASCADE)
    validated = models.BooleanField(default=False)
Run Code Online (Sandbox Code Playgroud)

ManyToManyField因此,A更像是一个使表示和查询更方便的概念。

  • @MarkyMark1000:是的,如果没有“ManyToManyField”,它仍然代表多对多关系。但是查询“Item”的“categories”可能会更麻烦。因此,`ManyToManyField` 在其之上添加了一个“概念层”,以便于使用 `myitem.categories.all()` 进行查询。 (2认同)