Django ForeignKey null = True无法从列中删除非null

时间:2013-08-07 19:06:01

标签: django foreign-keys foreign-key-relationship alter-table notnull

问题:

这是我的班级,有两个ForeignKey s(deptsalary_range)。注意null=True

class UserProfile(models.Model):
    user = models.OneToOneField(User, related_name='user_profile')
    avatar = models.CharField(max_length=300, default='/static/default.png')
    dept = models.ForeignKey(Department, null=True)
    salary_range = models.ForeignKey(SalaryRange, null=True)

正在运行python manage.py sqlall main似乎显示正确的sql(NOT NULLdept_id上没有salary_range_id

CREATE TABLE "main_userprofile" (
    "id" integer NOT NULL PRIMARY KEY,
    "user_id" integer NOT NULL UNIQUE REFERENCES "auth_user" ("id"),
    "avatar" varchar(300) NOT NULL,
    "dept_id" integer REFERENCES "main_department" ("id"),
    "salary_range_id" integer REFERENCES "main_salaryrange" ("id"),

但是在创建IntegrityError时会出现UserProfile

main_userprofile.dept_id may not be NULL

在检查数据库时,两列都设置为NOT NULL如何?为什么?

黑客:

我能想到的就是在syncdb之后改变表格:

ALTER TABLE main_userprofile ALTER COLUMN dept_id DROP NOT NULL;
ALTER TABLE main_userprofile ALTER COLUMN salary_range_id DROP NOT NULL;

这适用于Postgres,但sqlite没有ALTER COLUMN选项..

解决方案??

1 个答案:

答案 0 :(得分:4)

一切似乎都很好。根据评论中的建议,很可能是您第一次运行syncdb时,那时您没有null=Truedept的选项salary_range。然后你改变了你的代码,但没有修改表定义。要解决此问题,您可以通过删除NOT NULL部分来手动修复问题,也可以使用数据库迁移应用程序。最受欢迎的是迄今为止South。 South可以检测模型定义中的更改并对数据库应用适当的更改(称为数据库迁移),而不会丢失任何数据。南方文档非常好,所以你应该能够立即开始使用它。

PS - 在Django的未来版本(很可能是Django 1.7)中,迁移功能将直接集成到Django核心中,但在此之前,South必须这样做。