django:`unique = True`是否会阻止`IntegrityError`?

时间:2014-07-08 13:59:49

标签: python django

我意识到当我有一个简单的模型时:

class Category(models.Model):
    name  = models.CharField(max_length=128, unique=True)
    views = models.IntegerField(default=0)
    likes = models.IntegerField(default=0)

修饰符unique=True具有以下效果:当我向数据库添加类别(通过HTML表单)时,该类别具有数据库中已存在的实例的名称,应用程序不会崩溃。 相反,我可以访问form.errors,我可以打印到页面或终端。 如果我省略unique=True并尝试使用已存在的名称向数据库添加类别,则会收到IntegrityError并且我的应用程序崩溃。

所以在我看来,定义unique=True对于应用程序的行为非常重要。我想那时必须有其他同样重要的模型属性

在django文档中,我在哪里可以阅读有关此内容以及是否还有其他此类属性?

2 个答案:

答案 0 :(得分:2)

首先,您使用唯一约束创建了模型,因此数据库已经具有唯一约束。类似于(对于MySQL):

CONSTRAINT myapp_category UNIQUE (name)

现在,您可能正在使用ModelForm,它会选择此属性unique=True,并应用该验证。因此,您可以通过form.errors捕获错误并优雅地处理它。

删除属性时,数据库仍然具有约束,但ModelForm不会为您执行该验证,因此IntegrityError

所以,回答你的问题 - unique=True确实有助于防止在ModelForm的上下文中使用它时引发异常,或者你必须自己处理它以使其优雅地失败

要从数据库中删除unique约束,您必须使用south等迁移工具

答案 1 :(得分:1)

我的猜测是你有一个数据库模型,UNIQUE列上有name约束。如果您尝试插入两个具有相同名称的行,则数据库(通过数据库驱动程序)将抛出IntegrityError。这完全独立于django。

然后django有一个模型如何构建表单。如果省略unique=True,则django假定数据库中的列不是唯一的,并且不在表单验证步骤中添加必要的检查。

因此,您的表单与数据库之间的配置基本不匹配。

解决方案:

  • 确保表单和数据库列的约束始终相同
  • 编写您自己的自定义验证规则(请参阅django文档)。

或者:编写从数据库中获取唯一约束的代码,然后在创建表单时,检查是否设置了必要的属性以避免此错误。