【问题标题】:Django. Many-To-Many Field for form, but not for model姜戈。用于表单的多对多字段,但不适用于模型
【发布时间】:2011-11-20 08:55:04
【问题描述】:

我的数据库应该有一个类型为多对多的字段,但事实并非如此,我无法更改。

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

当我在数据库中保存学生时,如何在学生表单中嵌入某种可以更改学生学科数据的学科字段?问题是我无法更改数据库结构,因此只能在 Django 的帮助下完成。

【问题讨论】:

    标签: django django-forms django-orm


    【解决方案1】:

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

    查看文档:ManyToManyField

    您必须将 db_table 选项设置为中间表的名称(即学生科目)。那么一切都应该正常。

    编辑:
    考虑到您的评论,问题在于 Django 需要您的表未提供的特定命名约定(即 MODELNAME_id)。既然你说你不能改变桌子本身,你就得试试别的。
    您必须为中间表(students-subjects)创建一个额外的模型,并将字段“students”定义为学生模型的外键,将字段“subjects”定义为科目模型的外键。然后对于多对多字段,您使用中间表的名称指定选项“通过”。设置选项 '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

    【讨论】:

    • 我做到了,得到了 sql 错误。列名“subject_id”无效。中间表中没有“subject_id”字段。中间表中有“主题”字段和“学生”字段。 Django 试图向它们添加 '_id' 后缀。并且主题表有 id 字段,而不是 subject_id。我错过了什么?
    • 是的,谢谢。我看到了这篇文章。但是当我在“通过”参数的帮助下完成时,“主题”字段不能包含在 StudentAdmin 表单中:不能包含 ManyToManyField 字段“主题”,因为“主题”手动指定了“通过”模型。跨度>
    • 问题似乎是,通过选项旨在用于向中间表添加附加字段,这将使多对多字段的表单小部件不足以处理所有 (可能)需要输入。也许有一个不使用 through-option 的解决方案...
    • 在 Django Google 小组中有一篇文章准确地提到了您的问题以及我们尝试过的两种解决方案。事实证明,“通过”应该有效。但这也无济于事……groups.google.com/group/django-users/browse_thread/thread/…
    • 不知道我真的能做什么。尝试了一些带有 SmartManyToMany 字段的 sn-ps - 没有任何帮助。不能通过参数和小部件用于多对多。
    猜你喜欢
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 2016-01-19
    • 2016-01-18
    相关资源
    最近更新 更多