我应该在数据库模型中使用哪种验证?

时间:2011-06-01 14:52:42

标签: django django-models

我的表单验证器非常好,如果表单通过is_valid,则所有数据都可以在数据库中插入。我还应该在db模型上验证一些东西吗?还有什么可以在db端进行验证?因为现在,除了可能的唯一性(我不能从我的FormModel做),我想不出别的。

编辑: 我之前使用Rails做过一些工作,你可以在客户端使用JS验证表单,在服务器端使用模型验证验证表单。我在django中看到你可以在客户端验证,使用JS,在服务器端你有2个验证检查:表单和模型。这让我很困惑。

2 个答案:

答案 0 :(得分:2)

无论您是否从前端验证,都应在数据库中验证所有数据。第一个验证应该是数据类型,例如使用日期数据类型将确保没有非日期可以进入您的数据库。如果表之间存在关系,则必须在数据库级别强制执行。如果数据必须是唯一的,那么不在其上放置唯一索引是不负责任的。如果您有一组唯一允许的值,则将它们放在查找表中,并为该表添加一个forign键约束。

在数据库本身进行验证是至关重要的原因是用户界面不是唯一与数据库交互的东西(即使你认为它会是这样)。其他应用程序可能会这样做,人们将需要通过导入或查询窗口进行数据更改(以修复/更改大量数据,例如当客户端购买客户端B并且您需要将所有数据转换为客户端A时)。此外,如果更改应用程序界面,则可能会丢失重写中的一些关键数据完整性检查。数据完整性是数据库设计和维护中最关键的因素之一。如果您不能指望数据完整性,则您没有数据。我从来没有见过一个数据库,它可以让应用程序处理这些内容,而不会随着时间的推移而丢失数据完整性。请记住,数据库将远远超过当前的应用程序。人们仍将在未来几年内查看这些数据。应用程序通常不会考虑报告哪些数据完整性问题往往会被曝光。例如,您不想解释为什么您有10,000,000个订单,而无法确定他们被运往谁。

答案 1 :(得分:1)

如果您的数据具有始终有效的约束,则应在模型/数据库级别(以及可选的表单级别)强制它。除了检查验证的表单之外,您的数据库可以以多种方式输入。例如,有人可以直接使用django shell来保存模型,或者有人可以在管理界面中创建/编辑模型,或者某些后来的设计者以某种方式创建新表单,但不能正确验证。

当然,只有在数据存在其他限制时才需要这样做。如果您使用正确的字段类型,Django会自动验证存储正确值的字段等内容。例如,IntegerField验证确保它包含一个整数,EmailField检查,它是以有效电子邮件地址的形式输入的,django.contrib.localflavor.us.models.PhoneNumberField是美国电话号码等。注意,这只是如果您的模型具有正确的字段(例如,如果您使用CharField s用于电子邮件地址,则无法执行验证。

但是数据结构之间可能存在其他链接,您应该在其中编写自己的验证。例如,如果所有需要特殊说明的自定义订单(以及非自定义订单有时只有特殊说明),您应该检查以强制执行所有自定义订单在特殊说明字段中具有某些内容(并且可能具有一些最小长度)。


编辑:为了回应您的编辑,django中三个潜在验证的原因很简单 - 由于不同原因在不同点进行不同的验证。

客户端(javascript / jquery)验证根本不可信任,并且应该仅为用户提供便利,几乎是事后的想法(如果你想要一个漂亮的平滑界面)。 AFAIK,django没有JS验证,除非你使用像django-ajax-forms之类的外部包,但是你不相信验证是正确的。

其次,表单和模型验证之间存在差异。一个模型可以具有用于不同目的的多种形式。例如,您可能有一个带有评论模型的博客,并允许两种类型的用户发表评论:登录用户或匿名用户。匿名用户的表单可能需要在评论之前给出姓名/电子邮件,而登录用户的表单不需要这些字段。登录后的用户表单在视图中处理后,可能会在保存之前自动将登录用户的正确姓名和电子邮件地址添加到评论模型中。

相比之下,模型验证始终适用,并且在数据库级别始终为真,无论他们如何尝试保存数据。如果要确保某些条件始终适用,请确保它处于数据库级别。 (并且您不必在表单级别编写验证)。