Django.多对多字段适用于表单,但不适用于模型



我有一个数据库,应该有一个字段与类型多对多,但它不是,我不能改变这一点。

例如,我有一个学生列表和一个科目列表。主题应该是多对多字段在学生表,但正如我所说的,它不是。student表根本没有这个字段。但是还有另一个表student -subjects,它包含subject_id-student_id项。

我如何在学生形式嵌入某种主题字段,可以改变学生的主题数据,当我保存在数据库中的学生?问题是我不能改变数据库的结构,所以需要在Django的帮助下才能改变。

对于数据库表来说,不存在像外键那样的'多对多字段'。在数据库表示中,多对多关系是通过使用一个额外的表来实现的,该表将希望在关系中设置的记录的主键(通常是id)链接起来。在您的示例中,这是表格student -subjects。当你在模型中定义多对多关系时,Django会使用这个表。你根本不需要改变你的数据库结构,它会像现在一样完美地工作。

参见文档:ManyToManyField

您必须使用中间表的名称设置db_table选项(例如,students-subjects)。那么一切都应该正常。

编辑:
考虑到你的评论,问题是Django期望一个特定的命名约定(即MODELNAME_id),而你的表没有提供。既然你说你不能改变表本身,你必须尝试其他方法。
您必须为中间表(students-subjects)创建一个额外的Model,并将字段"students"定义为学生模型的外键,将字段"subjects"定义为主题模型的外键。然后,对于多对多字段,使用中间表的名称指定选项"through"。设置选项'db_column',让Django知道你想为数据库列使用哪些名称。在元类中需要'db_table'来指定数据库表名。

你会得到这样的东西:

class StudentsSubjects(models.Model):
    student = models.ForeignKey(Student, db_column='student')
    subject = models.ForeignKey(Subject, db_column='subject')
    class Meta:
        db_table = 'students-subjects'    
class Student(models.Model):
    ...
    subjects = models.ManyToManyField(Subject, through='StudentsSubjects')
    ...
class Subject(models.Model):
    ...

我希望这对你有帮助。有关更多详细信息,请参见:多对多关系上的额外字段。