简体   繁体   English

django:“ unique = True”会阻止“ IntegrityError”吗?

[英]django: Does `unique=True` prevent `IntegrityError`?

I realized that when I have a simple model: 我意识到,当我有一个简单的模型时:

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

the modifier unique=True has the effect that when I add a category to the database (via an HTML form) which has a name of an instance already present in the database, the application will not crash. 修饰符unique=True的作用是,当我将类别添加到数据库中(通过HTML表单)时,该类别的名称已经存在于数据库中,该应用程序不会崩溃。 Instead, I get access to form.errors which I can print to the page or to the terminal. 相反,我可以访问form.errors ,可以将其打印到页面或终端上。 If I omit unique=True and I try to add a category to the database with a name that already exists, I get an IntegrityError and my application crashes. 如果我省略unique=True并且尝试使用名称已经存在的类别添加到数据库中,则会收到IntegrityError并导致我的应用程序崩溃。

So it seems to me that defining unique=True is pretty important for the behaviour of the application. 因此在我看来,定义unique=True对于应用程序的行为非常重要。 I guess then there must be other model attributes which are equally importa 我想那一定还有其他同样重要的模型属性

In the django documentation, where can I read about this and if there are other such attributes? 在django文档中,我在哪里可以读到它以及是否还有其他此类属性?

First of all, you created the model using the unique constraint, so the database already has the unique constraint.Something like (for MySQL): 首先,您使用唯一约束创建了模型,因此数据库已经具有唯一约束,类似于(对于MySQL):

CONSTRAINT myapp_category UNIQUE (name)

Now, you are probably using a ModelForm , which picks this attribute unique=True , and applies that validation. 现在,您可能正在使用ModelForm ,它选择了这个属性unique=True ,并应用了该验证。 So, you can catch the errors via form.errors and handle it gracefully. 因此,您可以通过form.errors捕获错误并form.errors处理。

When you remove the attribute, the database still has the constraint, but the ModelForm does not perform that validation for you, hence the IntegrityError 当您删除属性时,数据库仍然具有约束,但是ModelForm不会为您执行该验证,因此会发生IntegrityError

So, to answer your question - unique=True does help prevent raising of an exception when you use it in the context of a ModelForm , or you would have to handle it yourself to make it fail gracefully. 因此,回答您的问题ModelForm unique=True确实有助于防止在ModelForm的上下文中使用异常时引发异常,否则您必须自己处理该异常以使其优雅地失败。

To remove the unique constraint from the database, you would have to use a migration tool like south 要从数据库中删除unique约束,您将不得不使用诸如south类的迁移工具

My guess is that you have a database model which has a UNIQUE constraint on the name column. 我的猜测是,您有一个对name列具有UNIQUE约束的数据库模型。 If you try to insert two rows with the same name, then the database (via the database driver) will throw an IntegrityError . 如果您尝试插入两个具有相同名称的行,则数据库(通过数据库驱动程序)将抛出IntegrityError This happens completely independent of django. 这完全独立于Django而发生。

django then has a model how to build forms. 然后,django有一个模型如何构建表单。 If you omit the unique=True , django assumes that the column in the database isn't unique and doesn't add the necessary checks in the form validation step. 如果省略unique=True ,则django会假设数据库中的列不是唯一的,并且不会在表单验证步骤中添加必要的检查。

So you basically have a config mismatch between your form and your database. 因此,您的表单和数据库之间基本上存在配置不匹配的情况。

Solutions: 解决方案:

  • Make sure the constraints for forms and database columns are always the same 确保表单和数据库列的约束始终相同
  • Write your own, custom validation rules (see the django documentation). 编写自己的自定义验证规则(请参阅django文档)。

Alternatively: Write code that gets unique constraints from the database and then, when you create a form, check that the necessary attributes are set to avoid this error. 或者:编写从数据库获取唯一约束的代码,然后在创建表单时,检查是否已设置必要的属性以避免此错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM