Django模型多对多和桥接表
我试图了解如何正确地设置模型,以便建立多对多关系,我注意到在创建模型时有一个多对多字段选项,但我似乎无法理解它的逻辑以及如何正确地使其工作。我想与大家分享我的代码,并在此过程中进行解释Django模型多对多和桥接表,django,python-3.x,django-models,Django,Python 3.x,Django Models,我试图了解如何正确地设置模型,以便建立多对多关系,我注意到在创建模型时有一个多对多字段选项,但我似乎无法理解它的逻辑以及如何正确地使其工作。我想与大家分享我的代码,并在此过程中进行解释 from django.db import models class Major(models.Model): name = models.CharField(max_length=30, db_index=True) class School(models.Model): name = mo
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)
注意,School表(Class)有一个多对多的专业表,这基本上就是我想要的,目标是允许一个数据库在单个学校下存储多个专业
在做了一些研究之后,我得出了这样的结论:这没有意义,最好创建一个桥接表,所以我决定像这样创建我的模型
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)
这不是一种更合适的设置db的方法,以便在学校中添加和删除多个专业,反之亦然
最好创建一个桥接表
这就是ManyToManyField
所做的。您的两个代码段在功能上完全相同
如果您可能需要through表上的一些额外数据(在Django world中称为through),例如第一次提供主修时的字段记录,您可以使用ManyToManyField
上的through
参数,如下所示:
来自django.db导入模型的
专业类别(型号.型号):
name=models.CharField(最大长度=30,db\u索引=True)
班级学校(模型。模型):
name=models.CharField(最大长度=30,db\u索引=True)
majors=models.ManyToManyField(Major,通过class='SchoolMajor')
学校专业班级(models.Model):
major=models.ForeignKey(major,on_delete=models.CASCADE)
school=models.ForeignKey(school,on_delete=models.CASCADE)
first_offered=models.DateField()
改编自。您的两个代码片段基本上没有区别。明确定义
学校专业
模式给你的印象是什么?(同样作为一个代码风格点,对于类使用大写
,对于模型使用单数名称)。我认为不会创建桥接数据库,谢谢您的澄清。对于如何填充桥接表,您有什么建议吗?我将使用包含数据的xlsx/csv文件来填充这些数据库,但我无法确定格式以及使用什么工具来填充这些数据,而不是手动将每个数据输入到/manage.py shell提供的shell中的for
循环中。对于本地开发和测试,shell
将非常有用。如果这是你需要经常做的事情,考虑把它变成A。至于实际创建数据本身,创建所有的专业
s,创建所有的学校
s,然后对于每个学校或专业,执行School.majors.add(Major)
或Major.schools.add(School)
,具体取决于您选择的学校。您还可以在最初创建数据之后,使用/manage.py dumpdata
,可以在以后使用/manage.py loaddata
将其还原到不同的数据库中。如果我在xlsx文件中有此数据,我会从网站上删除一些数据,并获得大量数据,如数千行,我基本上想以这样一种方式确定这些数据的方向,以便它能够填充数据库,这个装置很有趣,但我觉得格式化这些数据需要很长时间。我使用了一个填充脚本,它对xlsx文件格式和sqlite3非常有用,但由于它将由3个不同的表组成(一个是多对多),我想看看是否还有其他快捷方式。正如我所说的-shell中的for
循环用于本地开发和测试,然后,如果需要多次执行管理命令,请执行管理命令。