我是Django的新手,在阅读了许多文档/指南和Google搜索之后,我对进行验证的最佳实践方法仍然有些困惑。

似乎最好的验证方法是在Model级别,以确保始终应用它,而不管数据来自哪里(例如Django前端,某些JS服务器,API等)。 如果我在基本模型中重写Model save()方法来调用full_clean(),那似乎是确保已保存数据始终良好的最佳方法。

但是,我在项目中遇到了各种各样的问题。 显而易见的是,Django的ModelForms已经调用Model full_clean(),因此在这种情况下,我最终两次调用了它。 最重要的是,还有其他并发症,例如:

  • 如果有一个Model级别的方法可以保存其中包含另一个Model的复合模型(例如,某个Account内的Address),则我不能只保存Address,因为Account之后可能无法通过验证。 因此,我真的需要先验证两个模型,然后再保存它们(保持事务性)。 但是然后,我需要调用full_clean()进行验证,然后在save()期间再次调用它,使其变为现在调用的3倍。 这似乎很浪费,特别是因为某些验证方法已命中数据库(例如validate_unique)。

我正在考虑的一件事是使full_clean()更智能,即添加一些功能以检查自上次清理模型以来是否已更改该模型,然后仅再次运行它,但是从某种意义上来说,这似乎相当复杂每个模型可能涉及很多工作。

关于如何更好地处理此问题的任何建议? 提前致谢。

#1楼 票数:0

您可以尝试各种解决方案,但是会遇到问题,因为该框架不是按照这种方式设计的。 例如,如果save方法调用full_clean并因此引发ValidationError那么如何确保在所有地方(序列化程序,admin)都对其进行处理? 此外,您仍然可以调用update而不是保存并绕过验证。

我建议将验证逻辑放入clean方法中,然后让ModelForm调用它。 如果您使用的是django-rest-framework请将验证逻辑放入Serializer 如果您发现自己重复验证逻辑,只需将其抽象出来并在需要的地方重复使用。 调用save时,请确保模型有效。

#2楼 票数:0

在网上阅读了许多其他内容之后,我得出了与@zxzak建议相同的结论。 这有点令人困惑,因为有些人确实建议将验证调用放入模型中以确保始终使用它,但是总的来说,共识似乎是最好将调用验证的调用放入Forms和ModelForms中。

对于像我这样的Django新手来说,这有点违反直觉,因为我们认为Forms是表示层上的东西,再加上网站HTML,但实际上,它们可以被认为是模型层和某些东西之间的抽象中间层。向其提供数据(网站,API,文件导入)。 因此,如果按照惯例,您始终使用Forms在输入和模型之间传输数据,则可以保证在一定程度上可以对模型进行验证。

当然,有很多方法可以解决这个问题,但是,如果您没有遵循既定的约定和/或对程序进行不好的编程,那么无论如何总是如此。 例如,在批量创建/更新时,无论如何都不会使用save()。

只要您以智能方式做事并使用如上所述的Forms,它就可以使您的数据保持良好状态。 业务逻辑之外引入的任何坏数据,如果没有验证就直接保存到模型中,则很可能是坏数据,而不是无效数据,因此无论如何都不会被验证捕获,并且很可能被测试捕获,而不是从网站/ api / import输入的自由格式数据。

  ask by StrayOctopus translate from so

未解决问题?本站智能推荐:

1回复

如何在优雅地保存Django 1.5之前使用full_clean()进行数据验证?

我认为Django的模型验证对于那些不使用内置ModelForm的模型来说有点不方便,虽然不知道为什么。 首先,需要手动调用full_clean() 。 请注意,在调用模型的save()方法时,也不会自动调用full_clean(),也不会在模型化验证的结果中自动调用。在Mode
1回复

django验证多个内联表单

我正在使用Django管理界面和Modelform表单验证。 我的一个模型出现问题,我想不出一种方法来让内联表单检查字段的唯一性。 例如,有两个内联对象,其字段为“名称”。 如果两个名称相同,我想提出一个验证错误。 从我所看到的来看,每个内联都被验证为单独的表单,因此很难将它们绑
1回复

Django错误:一个或多个模型未验证:

我正在从Netutus http://net.tutsplus.com/tutorials/python-tutorials/building-ribbit-with-django/制作应用程序,当我运行syncdb时出现此错误。 我做了一些研究,我发现我必须在ForeignKey中放入一个r
1回复

具有多个参数的简单Django验证问题

我已经和Django玩了几天,偶然发现了以下问题。 我有以下型号: 我想做的是创建一个不允许分配时间重叠的验证器。 该算法非常简单,但是我不知道如何使用验证器正确设置它。 我以为是这样的: 顺便说一句,我写了这些%theDateValue%和%aReferenceToT
1回复

如何获取Django表单以一起验证多个字段

我正在尝试编写一个clean方法来验证3个字段(百分比)是否总计为零。 我遵循了django 文档 ,并向表单类添加了clean()方法,但是Django在表单提交后仍会重定向,表明is_valid()函数已成功传递。 似乎clean方法仅由Django is_valid()调用,并且不
3回复

Django:表单验证:接受一个字段的多个值

我希望创建一个表单字段,该字段为给定字段采用多个值,验证它们并将它们存储为列表。 例如,可以运行以下 curl 命令并发布几个名为“email”的 POST 参数 在我看来,我可以执行以下操作以直接从 POST 数据中获取电子邮件列表。 但是,我想利用表单验证来清除 POST 数据中指定的
1回复

Django在单个Form实例中存在多个Forms,验证错误

注册表格包含多个ContactForm和一个FeeForm,我尝试验证FeeForm,注册表格中存在ContactForms,验证失败并且它没有显示任何验证错误,对于FeeForm的空白字段,Contact Forms forms.py Views.py template.
2回复

Django验证

我来自Ruby on Rails背景,我刚刚在Django中启动了这个项目。 我开始弄乱模型,只是发现出于兼容性问题,Django在保存之前不对模型实例进行full_clean(验证)。 好,很奇怪 第二个惊喜如下: 我创建了一个带有BooleanField类型的现场te