在 Django 中分离表单输入和模型验证?
Posted
技术标签:
【中文标题】在 Django 中分离表单输入和模型验证?【英文标题】:Separating form input and model validation in Django? 【发布时间】:2012-02-21 20:49:42 【问题描述】:在 Django 项目中将输入验证与模型级验证分开是否很典型?例如,验证用户名是否符合命名标准将是输入验证,验证用户是否已在数据库中将是模型级验证。
我一直在查看一位同事的代码,他们将这两种类型的验证都放在了一个表单类中(在 forms.py 中)。这是典型的设置,还是更常见的是模型级验证出现在模型或视图中?
或者有没有更好的方法来解决这个问题——比如使用ModelForm
?我对 Django 很陌生,并试图了解在这种情况下推荐的模式是什么。
【问题讨论】:
【参考方案1】:这是一个非常有趣的问题(对我来说)。
在我看来,所有的验证代码都应该移到模型代码中。这是不违反业务规则的方法。当验证代码在模型中时,不可能忘记新表单中的某些验证或在多个表单中存在不一致的规则。
我链接到您'Django, Raise a validation error in a model's save method' 与您的问题相关的问题。下面的问题您可以看到如何将代码验证从表单转移到模型。我希望这个简短的介绍可以对你有所帮助。
你来自什么框架?验证规则在您的环境中是如何编写的?
【讨论】:
我同意。大多数事情真的可以被认为是“模型级”验证。如果用户名不符合命名标准,您真的不希望用户名访问数据库。有些事情会因表单而异,这就是您要在表单本身上验证的地方。您可能有一个花哨的 File 模型,它在字段中保存文件类型。在模型级别任何类型都可以,但在照片上传表单中,您希望将其限制为 png 和 jpeg,例如。【参考方案2】:我不同意接受的答案。我更喜欢使用模型级验证来避免模型不一致,并使用表单级验证来解决任何特定于站点的限制。
假设我们有一个事件模型,其中datetime
字段用于开始和结束时间。模型验证将迫使我们的结束时间在开始时间之后。但是,我会将其保留在表单中以验证新创建的事件是否不是过去的。因此,如果我必须添加过去发生的事件,我可以使用允许过去日期的管理员特定表单,或者直接将其添加到数据库中。
因此,模型验证应该只检查明显错误的值。但是如果你需要做一些时髦的事情(例如,机器人用户名中的 Unicode 字符),它应该让你去做,即使它只是通过管理员或外壳。我在 *** 上阅读了一个答案,该答案建议始终在后端代码中使用表单,用 form["field"] = "value"
之类的代码填充字段,以从一致的验证中受益。
【讨论】:
对于您的示例场景,您可以在event
表上设置 userId 字段,并允许为某些组用户填写过去日期的表单。对于您发布的每个示例,我都可以找到这样的反例;)但这是我的方法,我确信对于某些规则,表单验证将是最好的解决方案。
当然你也可以在模型中实现它,但是你正在将功能烘焙到应该是表单的东西中。如果您想在其他地方重用您的博客模型,为什么要关心帖子是否属于名为“admin”的组中的用户?由于此要求可以从一个站点更改为另一个站点,因此最好将其留给表单而不是模型本身。
或许,在未来,你的 web 应用会有一个完整的 rest api。只是一个例子。感谢您分享您的评论,欢迎。以上是关于在 Django 中分离表单输入和模型验证?的主要内容,如果未能解决你的问题,请参考以下文章