DJANGO:与附加字段的多对多关系

Posted

技术标签:

【中文标题】DJANGO:与附加字段的多对多关系【英文标题】:DJANGO: many-to-many relationship with additional fields 【发布时间】:2012-03-25 11:06:17 【问题描述】:

编程新手,这对我来说很困惑...我有 2 个模型。部门和跨职能项目。两个模型之间的关系创建了一个名为 Department_Crossfunctionalproject 的连接表。

我有另一个模型,叫做雇员。我想将员工添加到 Department_Crossfunctionalproject 表。我怎样才能做到这一点?

我一直在关注本教程:https://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships。我不能在 DJANGO 创建的自动创建的 department_crossfunctionalproject 连接表上执行此操作吗?

我不断收到以下错误:

CommandError("One or more models did not validate:\n%s" % error_text) 
django.core.management.base.CommandError: One or more models did not validate:
companydatabase.membership:"Department_crossfunctionalproject" has a relationship with model <class 'companydatabase.models.Department_crossfunctionalproject'>, 
which has either not been installed or is abstract.

型号:

class Crossfunctionalproject(models.Model):
    nameofproject = models.CharField(max_length=50)
    def __unicode__(self):
        return self.nameofproject

class Department(models.Model):
    name = models.CharField(max_length=100)
    project = models.ManyToManyField(Crossfunctionalproject, null=True, blank=True)

class Employee(models.Model):
    employeenumber = models.CharField(max_length=50)
    fname = models.CharField(max_length=50, verbose_name='First Name')
    mname = models.CharField(max_length=50, null=True, blank=True, verbose_name='Middle Name')
    lname = models.CharField(max_length=50, verbose_name='Last Name')
    email = models.EmailField(null=True, blank=True, verbose_name='Email')
    phone = models.CharField(max_length=50, null=True, blank=True, verbose_name='Phone')
    title = models.CharField(max_length=50, null=True, blank=True, verbose_name='Position')

# db table created by DJANGO, I wrote out the model, trying to add extra columns*
class Department_crossfunctionalproject(models.Model):
    department = models.ForeignKey(Department)
    crossfunctionalproject = models.ForeignKey(Crossfunctonalproject)
    membership = models.ManyToManyField(Employee, through="Membership")

class Membership(models.Model):
    employee = models.ForeignKey(Employee)
    department_crossfunctionalproject = models.ForeignKey(Department_crossfunctionalproject)    
    whytheyjoined = models.CharField(max_length=100)

【问题讨论】:

您在Employee.title.verbose_name 中有一个错误 -> 最后缺少' 谢谢,将代码复制到这里时出错 【参考方案1】:

问题是您在“员工”之前定义了Department_Crossfunctionalproject。尝试将Employee 模型的名称作为字符串提供:

membership = models.ManyToManyField('Employee', through="Membership")

【讨论】:

我将employee模型移到department_crossfunctionalproject上方,并尝试将employee作为字符串,但我仍然无法让runserver工作..仍然在shell中收到相同的错误命令... 不要忘记重新生成数据库。如果你不使用类似南的东西,那么你将不得不删除这个应用程序中的表格和python manage.py syncdb 我尝试重新生成数据库,但是当我运行 python manage.py syncdb 时出现错误消息:错误:一个或多个模型未验证:companydb.membership:'department_crossfunctionalproject' 与模型 ,它要么未安装,要么是抽象的。【参考方案2】:

Syncdb 命令为 INSTALLED_APPS 中尚未创建表的所有应用程序创建数据库表。它永远不会发出 ALTER TABLE 语句来匹配安装后对模型类所做的更改。 如果您手动更改了 Department_Crossfunctionalproject 模型,则必须删除表并再次运行 syncdb。

syncdb in django manual

【讨论】:

所以我没有运行 python manage.py syncdb 命令来创建表,我是手动完成的。但是我删除了 department_crossfunctionalproject 以尝试使用 syncdb 以及成员资格表,我收到一条错误消息:一个或多个模型未验证:companydb.membership: 'department_crossfunctionalproject' has a relationship with model ,要么没有安装,要么是抽象的。 还有一些错别字。 Department_Crossfunctionalproject 在类声明行中缺少冒号。类成员中的 Department_Crossfunctionalproject 成员不能为大写。 谢谢,已更正。这些是复制代码时产生的错误。 Department_Crossfunctionalproject crossfunctionalproject = models.ForeignKey(Crossfunctonalproject) 也来自抄袭? 当我尝试 syncdb 时,我得到了与字段名称冲突相关的不同错误。【参考方案3】:

我喜欢使用 South 管理对我的模型的更改:http://south.aeracode.org/

Django 不处理删除列,所以我开始使用它。

【讨论】:

【参考方案4】:

我收到了类似的错误消息,但问题的原因不同,因此修复程序也不同。 我的问题是包含每个类定义的文件没有“导入”另一个类

我收到以下错误:

django.contrib.staticfiles.management.commands.runserver.Command 对象的绑定方法 Command.inner_run 在 0x010E2170 启动的线程中未处理的异常

文件“C:\ ...\lib\site-packages\django\core\management\base.py”,第 284 行,验证中

raise CommandError("一个或多个模型没有验证:\n%s" % error_text)

django.core.management.base.CommandError:一个或多个模型未验证: app_name.studio: 'instructors' 与模型 Instructor 具有 m2m 关系,该模型尚未安装或抽象。

我在 Studio 和 Instructor 类之间定义了多对多关系。每个类都定义在models目录的单独文件中(不在同一个models.py文件中)

在 app_name/models/studio.py 中:

class Studio(models.Model):
    instructors = models.ManyToManyField("Instructor", blank=True, null=True, db_table="app_name_instructor_studios")

在 app_name/models/instructor.py 中:

class Instructor(models.Model):
    studios = models.ManyToManyField("Studio", blank=True, null=True, db_table="app_name_instructor_studios")

解决方案:

我在 app_name/models/__init.py__ 文件中添加了缺失的导入语句,如 in this post

所述
from instructor import *

我能够解决它的另一种方法是在 app_name/models/studio.py 文件中显式导入 Instructor 类(但我更喜欢第一个解决方案):

from app_name.models.instructor import Instructor

【讨论】:

以上是关于DJANGO:与附加字段的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

在 django 的多对多关系中添加额外的字段

CASCADE 究竟如何与 Django 中的多对多字段一起工作

如何过滤和访问 Django QuerySet 中的多对多字段?

使 ModelForm 与 Django 中的中间模型的多对多关系工作的步骤是啥?

将 Django 中的多对多关系表示为两个多项选择

多维数据集设计 - 带有附加列的多对多映射的桥接表