模型验证和完整性错误

问题描述

当我的模型需要特殊验证时,我通常首先考虑db约束以完全确保数据库的完整性,但是我发现这种方法存在一些问题。我通常使用UniqueConstraints,例如:

            models.UniqueConstraint(
                fields=('author','title'),name='valid_unique_author_title',),

,它们之所以工作良好,是因为表单和序列化程序会捕获错误显示类似Post with this Author and Title already exists.错误,但是UniqueConstraint发生的情况具有类似条件

            models.UniqueConstraint(
                fields=('author',condition=models.Q(title='title1'),name='valid_unique_title1_author_title',

与预期的相反,它们抛出一个完整性错误,该错误不会被表单和序列化器(DRF)捕获,从而导致HTTP响应以500作为状态码,仅通过添加条件便不再捕获该错误。第一个问题,我必须修改所有具有检查约束或具有唯一约束的表格和序列化程序,并带有捕获完整性错误的条件吗?

最后,相同的CheckConstraints也是如此:

            models.CheckConstraint(
                check=~models.Q(title='forbidden_title'),name='valid_forbidden_title'
            ),

上述示例有所不同,我发现了两种约束条件:

  • 对比赛条件不敏感。检查约束,用于验证forbidden_title标题是否不同。
  • 容易受到比赛条件的影响。第二个UniqueConstraint,用于验证当标题等于title1时作者是否还有其他标题相同的帖子。我可以在表格或序列化器中验证约束,但仍可能出现竞争条件。

我发现了一些有关如何管理此类错误评论,并且大多数仅以序列化程序的形式进行验证。第二个约束条件的一个例子(每个标题title1用户只有一个帖子)

 new_post_title = 'title'
 user_request = request.user

if new_post_title == 'title1':
  post_exists = user_request.posts.filter(title='title1').exists()
  if post_exists: 
    raise ValidationError(.....)

并且如果由于某种原因发生了引发完整性错误的竞争条件,则他们只会忽略此情况,并且服务器响应为A 500状态代码。我想我同意这一点,但是为什么不将验证放在模型的clean方法中呢?。

当我以admin表单创建新对象时,这是模型中验证功能的堆栈跟踪。

  1. 调用模型的full_clean方法(此方法调用接下来的三个函数)。
  2. 调用模型的clean方法
  3. 调用模型的clean_fields
  4. 调用模型的validate_unique
  5. 调用模型的save方法

我可以将验证放到干净的地方,并且不仅可以在表单中验证,而且.....窗体有一些技巧,因为认情况下,如果我创建了save方法,则认不会在save方法调用clean,clean_fields和validate_unique。 shell中的post对象,唯一可以调用函数save,所以...我可以在full_clean方法调用save方法,此函数负责call clean,clean_fields和validate_unique(供表单使用),结果类似于:


    def save(self,force_insert=False,force_update=False,using=None,update_fields=None):
        self.full_clean()
        return super().save(force_insert=force_insert,force_update=force_update,using=using,update_fields=update_fields)

一切似乎都是完美的,因为验证是在序列化程序,表单,shell中验证的,但是....表单在调用模型中的full_clean之前先调用save,然后在模型中调用{{ 1}}再次调用save,这不是我遇到的唯一问题,当我使用full_clean表达式并调用F方法时,验证会引发TypeError,因为使用save表达式的字段不是有效类型(它们不是整数或str,它们是F表达式)。

那么,什么是最佳解决方案?

更新了25/08/2020 我发现了将F方法添加full_clean方法中的方法的其他方面。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...