Django: `unique=True`能防止`IntegrityError`吗?

2 投票
2 回答
1899 浏览
提问于 2025-04-18 12:30

我发现,当我有一个简单的模型时:

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 个回答

1

我猜你的数据库模型中,name这一列有一个UNIQUE的限制。这意味着如果你尝试插入两行相同名字的数据,数据库(通过数据库驱动)会报一个IntegrityError的错误。这种情况和django没有关系,是数据库自己处理的。

django有一种方式来构建表单。如果你没有设置unique=True,django就会认为数据库中的这一列不是唯一的,因此在表单验证时不会进行必要的检查。

所以,你的表单和数据库之间的配置就不一致了。

解决办法:

  • 确保表单和数据库列的限制始终保持一致
  • 编写你自己的自定义验证规则(可以参考django的文档)。

另外,你也可以写代码从数据库获取唯一性限制,然后在创建表单时检查必要的属性,以避免这个错误。

2

首先,你创建模型的时候用了唯一约束,这样数据库里就已经有了这个唯一约束。比如在MySQL中是这样的:

CONSTRAINT myapp_category UNIQUE (name)

现在,你可能在使用一个叫ModelForm的东西,它会自动检查这个unique=True的属性,并进行验证。所以,你可以通过form.errors来捕捉错误,并优雅地处理它们。

如果你去掉这个属性,数据库里还是有这个约束的,但ModelForm就不会再为你做这个验证了,因此就会出现IntegrityError的错误。

所以,回答你的问题——在ModelForm的上下文中,unique=True确实可以帮助你避免抛出异常,否则你就得自己处理这个错误,让它优雅地失败。

如果你想从数据库中移除unique约束,你需要使用像south这样的迁移工具。

撰写回答