Django的。多对多字段用于表单,但不用于模型

时间:2011-09-19 15:40:10

标签: django django-forms django-orm

我的DB应该有一个类型为Many-To-Many的字段,但它不是,我无法改变它。

例如,我有一份学生名单和一系列科目。主题应该是学生表中的多对多字段,但正如我所说的那样。学生桌根本没有这个字段。但是还有另一个表学生 - 主题包含subject_id-student_id项目。

当我将学生保存在数据库中时,如何在学生表格中嵌入某些可能会改变学生科目数据的科目?问题是我不能改变数据库结构,所以只需要在Django的帮助下完成它。

1 个答案:

答案 0 :(得分:1)

对于像您可能知道外键的数据库表,没有“多对多字段”这样的东西。在数据库表示中,通过使用一个额外的表来实现多对多关系,该表链接要关联的记录的主键(通常是id)。在你的情况下,这是表学生 - 科目。当您在模型中定义多对多关系时,Django使用此表。您根本不需要更改数据库结构,它将像现在一样完美地工作。

请参阅文档:ManyToManyField

您必须使用中间表的名称(即学生 - 主题)设置db_table选项。然后一切都应该正常。

编辑:
考虑到你的评论,问题是Django期望你的表不提供某种命名约定(即MODELNAME_id)。既然你说你不能改变表本身,你必须尝试别的东西 您必须为中间表(学生 - 科目)创建一个额外的模型,并将“学生”字段定义为学生模型的外键,将“科目”字段定义为科目模型的外键。然后,对于多对多字段,您可以使用中间表的名称指定选项“通过”。设置选项'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):
    ...

我希望这会对你有所帮助 有关更多详细信息,请参阅:Extra fields on many-to-many relationship