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

时间:2022-10-04 12:58:46

I have DB that should have one field with type Many-To-Many, but it is not and I can't change this.

我有一个DB应该有一个类型为多对多的字段,但它不是,我不能改变它。

For example I have a list of students and a list of subjects. Subject should be many-to-many field in students table, but as i said it is not. Students table doesn't have this field at all. But there is still another table students-subjects that contains subject_id-student_id items.

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

How can I embed in student form some kind of subject field that could change students-subjects data when I save a student in DB? The problem is that I can't change the DB structure so need to make it only with help of Django.

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

1 个解决方案

#1


1  

There is no such thing as a 'Many-to-many field' for a database-table like you might know it of foreign keys. In database representation many-to-many relationships are realized by using an extra table that links the primary keys (usually the ids) of the records you want to set in relation. In your case that is the table students-subjects. Django uses this table when you define a many-to-many relationship in the model. You do not have to change your database structure at all, it will be working perfectly as it is now.

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

See the documentation: ManyToManyField

请参阅文档:ManyToManyField

You'll have to set the db_table option with the name of your intermediary table (i.e. students-subjects). Then everything should work fine.

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

EDIT:
Considering your comment, the problem is that Django expects a certain naming convention (i.e. MODELNAME_id) which isn't provided by your table. Since you say that you cannot change the table itself, you have to try something else.
You have to create an extra Model for your intermediary table (students-subjects) and define the field 'students' as a foreign key to the students model and the field 'subjects' as a foreign key to the subjects model. Then for the many-to-many field you specifiy the option 'through' with the name of your intermediary table. Set the options 'db_column' to let Django know which names you'd like to use for the databse columns. 'db_table' in the meta class is needed to specify your database table name.

编辑:考虑到你的评论,问题是Django期望你的表不提供某种命名约定(即MODELNAME_id)。既然你说你不能改变表本身,你必须尝试别的东西。您必须为您的中间表(学生 - 主题)创建一个额外的模型,并将“学生”字段定义为学生模型的外键,将“主题”字段定义为主题模型的外键。然后,对于多对多字段,您可以使用中间表的名称指定选项“通过”。设置选项'db_column'让Django知道您想要用于数据库列的名称。需要元类中的“db_table”来指定数据库表名。

You get something like:

你会得到类似的东西:

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):
    ...

I hope that will help you.
For more detail see: Extra fields on many-to-many relationship.

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

#1


1  

There is no such thing as a 'Many-to-many field' for a database-table like you might know it of foreign keys. In database representation many-to-many relationships are realized by using an extra table that links the primary keys (usually the ids) of the records you want to set in relation. In your case that is the table students-subjects. Django uses this table when you define a many-to-many relationship in the model. You do not have to change your database structure at all, it will be working perfectly as it is now.

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

See the documentation: ManyToManyField

请参阅文档:ManyToManyField

You'll have to set the db_table option with the name of your intermediary table (i.e. students-subjects). Then everything should work fine.

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

EDIT:
Considering your comment, the problem is that Django expects a certain naming convention (i.e. MODELNAME_id) which isn't provided by your table. Since you say that you cannot change the table itself, you have to try something else.
You have to create an extra Model for your intermediary table (students-subjects) and define the field 'students' as a foreign key to the students model and the field 'subjects' as a foreign key to the subjects model. Then for the many-to-many field you specifiy the option 'through' with the name of your intermediary table. Set the options 'db_column' to let Django know which names you'd like to use for the databse columns. 'db_table' in the meta class is needed to specify your database table name.

编辑:考虑到你的评论,问题是Django期望你的表不提供某种命名约定(即MODELNAME_id)。既然你说你不能改变表本身,你必须尝试别的东西。您必须为您的中间表(学生 - 主题)创建一个额外的模型,并将“学生”字段定义为学生模型的外键,将“主题”字段定义为主题模型的外键。然后,对于多对多字段,您可以使用中间表的名称指定选项“通过”。设置选项'db_column'让Django知道您想要用于数据库列的名称。需要元类中的“db_table”来指定数据库表名。

You get something like:

你会得到类似的东西:

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):
    ...

I hope that will help you.
For more detail see: Extra fields on many-to-many relationship.

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