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' 与模型 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 modelcrossfunctionalproject = 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:与附加字段的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章
CASCADE 究竟如何与 Django 中的多对多字段一起工作
如何过滤和访问 Django QuerySet 中的多对多字段?