Django: `unique=True`能防止`IntegrityError`吗?
我发现,当我有一个简单的模型时:
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 个回答
我猜你的数据库模型中,name
这一列有一个UNIQUE
的限制。这意味着如果你尝试插入两行相同名字的数据,数据库(通过数据库驱动)会报一个IntegrityError
的错误。这种情况和django没有关系,是数据库自己处理的。
django有一种方式来构建表单。如果你没有设置unique=True
,django就会认为数据库中的这一列不是唯一的,因此在表单验证时不会进行必要的检查。
所以,你的表单和数据库之间的配置就不一致了。
解决办法:
- 确保表单和数据库列的限制始终保持一致
- 编写你自己的自定义验证规则(可以参考django的文档)。
另外,你也可以写代码从数据库获取唯一性限制,然后在创建表单时检查必要的属性,以避免这个错误。
首先,你创建模型的时候用了唯一约束,这样数据库里就已经有了这个唯一约束。比如在MySQL中是这样的:
CONSTRAINT myapp_category UNIQUE (name)
现在,你可能在使用一个叫ModelForm
的东西,它会自动检查这个unique=True
的属性,并进行验证。所以,你可以通过form.errors
来捕捉错误,并优雅地处理它们。
如果你去掉这个属性,数据库里还是有这个约束的,但ModelForm
就不会再为你做这个验证了,因此就会出现IntegrityError
的错误。
所以,回答你的问题——在ModelForm
的上下文中,unique=True
确实可以帮助你避免抛出异常,否则你就得自己处理这个错误,让它优雅地失败。
如果你想从数据库中移除unique
约束,你需要使用像south
这样的迁移工具。