ORM的分离和验证

时间:2009-07-10 11:09:38

标签: python django validation architecture django-models

我使用django,我想知道在什么情况下应该进行模型验证。至少有两种变体:

  1. 在模型的save方法中验证并在违反业务规则时引发IntegrityError或其他异常
  2. 使用表单和内置的clean_ *设施验证数据
  3. 从一个角度来看,答案很明显:应该使用基于表单的验证。这是因为ORM是ORM,验证完全是另一个概念。看看CharField:forms.CharField允许min_length规范,但models.CharField不允许。 好的很酷,但是django.db.models中验证功能到底是怎么回事?我可以指定CharField不能为空,我可以在python中使用EmailField,FileField,SlugField验证,而不是在RDBMS上。此外,还有URLField,用于检查涉及一些非常复杂的逻辑的URL的 existance

    从另一方面来说,如果我有一个实体,我想保证它不会以不一致的状态保存,无论是来自某个表单,还是由某些内部算法修改/创建的。我有一个名字字段的模型,我希望它应该长于一个字符。我也有一个min_age和一个max_age字段,如果min_age>则没有多大意义。 MAX_AGE。那么我应该在保存方法中检查这些条件吗?

    模型验证的最佳做法是什么?

5 个答案:

答案 0 :(得分:0)

我不确定这是否是最佳做法,但我所做的是在将数据推送到数据库之前,我倾向于验证客户端和服务器端。我知道这需要更多的努力,但这可以通过在使用前设置一些值然后维护它们来完成。

您还可以尝试使用** kwargs将大小限制推入到put()调用之前调用的验证函数中。

答案 1 :(得分:0)

你有两个不同的选择。

  • 基于表单的验证可视为语法验证+将HTTP请求参数从文本转换为Python类型。
  • 基于模型的验证可以被视为语义验证,有时使用HTTP /表单层中不可用的上下文。

当然,在DB中有第三层强制执行约束,并且由于并发请求更新数据库(例如唯一性约束,乐观锁定),因此可能无法在其他任何地方检查。

答案 2 :(得分:0)

正在进行的Google Summer of Code项目旨在为Django模型层带来验证。您可以在GSoC学生(Honza Kral)的this presentation中阅读更多相关信息。还有github repository的初步代码。

在代码进入Django版本之前,一种推荐的方法是使用ModelForms验证数据,即使源不是表单。它在一个Django核心开发者的this blog entry中描述。

答案 3 :(得分:0)

“但是,验证功能在django.db.models中的作用到底是什么?”

一句话:遗产。 Django的早期版本具有不太健壮的形式,并且验证分散。

“我应该在保存方法中检查这些条件吗?”

不,您应该使用表单进行所有验证。

“模型验证的最佳做法是什么?”*

使用表单进行所有验证。

“是来自表单还是由某些内部算法修改/创建”

什么?如果您的算法遭受精神病发作或您的程序员是反社会人员,那么 - 也许 - 您必须验证内部生成的数据。

否则,内部生成的数据 - 根据定义 - 是有效的。只有用户数据可能无效。如果您不信任您的软件,那么写它的重点是什么?您的单元测试是否已损坏?

答案 4 :(得分:0)

数据库/模型验证

数据库中的数据存储必须始终处于某种形式/状态。例如:必需的名字,姓氏,外键,唯一约束。这就是你app的逻辑所在。无论您认为数据来自何处 - 都应该在此处“验证”,如果不满足要求则会引发异常。

表单验证

输入的数据应该看起来。如果通过其他方式(通过admin或api调用)以不同方式输入此数据,则可以。 例子:人名的长度,句子的适当大写......

Example1 :对象有 StartDate EndDate StartDate 必须始终位于 EndDate 之前。你在哪里验证这个?在模型当然!考虑一下您可能从其他系统导入数据的情况 - 您不希望这样做。

示例2 :密码确认。您有一个用于在db中存储密码的字段。但是,您在表单上显示两个字段:password1和password2。表单和表单只负责比较这两个字段,看它们是否相同。表单有效后,您可以安全地将password1字段作为密码存储到数据库中。