Django 模型多对多和桥接表

dav*_*yan 7 django django-models python-3.x

我试图了解如何正确设置模型以建立多对多关系,我注意到创建模型时有一个 ManyToManyField 选项,但我似乎无法理解它的逻辑以及如何正确地使其发挥作用。我想分享我的代码并一路解释。

from django.db import models

class Major(models.Model):
    name = models.CharField(max_length=30, db_index=True)

class School(models.Model):
    name = models.Charfield(max_length=50, db_index=True)
    majors = models.ManyToManyField(Major)

class Professor(models.Model):
    ProfessorIDS = models.IntegerField()
    ProfessorName = models.CharField(max_length=100)
    ProfessorRating = models.DecimalField(decimal_places=2,max_digits=4)
    NumberOfRatings = models.CharField(max_length=50)
    school = models.ForeignKey(School , on_delete=models.CASCADE)
    major = models.ForeignKey(Major , on_delete=models.CASCADE)
Run Code Online (Sandbox Code Playgroud)

请注意,学校表(班级)有一个多对多的专业,这本质上就是我想要的,目标是拥有一个允许在单个学校下存储多个专业的数据库。

经过一些研究后,我得出的结论是,这没有意义,最好创建一个桥接表,所以我决定像这样创建我的模型......

from django.db import models

class Major(models.Model):
    name = models.CharField(max_length=30, db_index=True)

class School(models.Model):
    name = models.Charfield(max_length=50, db_index=True)


class School_Majors(models.Model):
    school = models.ForeignKey(School, on_delete=models.CASCADE)
    major = models.ForeignKey(Major, on_delete=models.CASCADE)

class Professor(models.Model):
    ProfessorIDS = models.IntegerField()
    ProfessorName = models.CharField(max_length=100)
    ProfessorRating = models.DecimalField(decimal_places=2,max_digits=4)
    NumberOfRatings = models.CharField(max_length=50)
    school = models.ForeignKey(School , on_delete=models.CASCADE)
    major = models.ForeignKey(Major , on_delete=models.CASCADE)
Run Code Online (Sandbox Code Playgroud)

这不是设置数据库以便在学校中添加和删除多个专业的更正确方法吗?反之亦然?

Ada*_*nes 13

最好创建一个桥接表

这就是 aManyToManyField所做的。您的两个片段在功能上是相同的。

如果您可能需要 through 表(在 Django 世界中如此称呼)上有一些额外的数据,例如首次提供专业时的字段记录,您可以使用through上的参数ManyToManyField,如下所示:

from django.db import models

class Major(models.Model):
    name = models.CharField(max_length=30, db_index=True)


class School(models.Model):
    name = models.CharField(max_length=30, db_index=True)
    majors = models.ManyToManyField(Major, through='SchoolMajor')


class SchoolMajor(models.Model):
    major = models.ForeignKey(Major, on_delete=models.CASCADE)
    school = models.ForeignKey(School, on_delete=models.CASCADE)
    first_offered = models.DateField()
Run Code Online (Sandbox Code Playgroud)

改编自这里