为啥 Django Rest Framework 不鼓励模型级别验证?
Posted
技术标签:
【中文标题】为啥 Django Rest Framework 不鼓励模型级别验证?【英文标题】:Why does Django Rest Framework discourage model level validation?为什么 Django Rest Framework 不鼓励模型级别验证? 【发布时间】:2015-12-26 08:19:00 【问题描述】:Django Rest Framework 序列化器在验证模型序列化器时不会调用Model.clean
。给出的解释是,这会导致“更清晰的关注点分离”,from the Django Rest Framework 3.0 release notes:
ModelSerializer 验证和 ModelForm 的区别。
这一变化也意味着我们不再使用
.full_clean()
方法 在模型实例上,而是显式地执行所有验证 序列化器。这提供了更干净的分离,并确保 ModelSerializer 类没有自动验证行为 这也不能在常规的 Serializer 类上轻松复制。
但是 Django Rest Framework 的作者试图分离的关注点是什么?
我的猜测是他们说模型实例不应该关心它自己的有效性。如果是这样,我不明白为什么。
【问题讨论】:
我在这个问题上支持你,当 Django Admin、Django Forms、Shell 等调用 clean 方法时,DRF 不调用它是完全出乎意料的。这是多余的为我们的开发人员工作。 【参考方案1】:模型的“full_clean”有两个主要问题。
第一个是技术性的。有几种情况根本没有调用 full_clean。例如,当您执行queryset.update()
时,您将绕过它。
第二个问题是,如果您有一个复杂的业务逻辑 - 这通常是您需要 full_clean 的原因 - 您可能应该在业务逻辑中进行验证,而不是深入到模型进行验证。 每一层都应该负责自己的一致性,而存储层(即模型)不应该关心业务层。
我能想到的另一件事是,一旦您拥有一个在序列化程序进行验证之后出现的模型,就会调用 full_clean。此时,事情开始变得混乱,因为您有一个两步验证,其中创建了一个对象。
如果您使用nested serializer
,您可能会被困在这里,因为在保存主模型之前您将无法创建嵌套模型,这将使完全干净的调用更加混乱 - 将创建一些对象,其他人不会。很难弄清楚应该在什么时候以及什么对象应该用他们的 full_clean 来验证,你可以肯定会有很多来自用户的抱怨,当他们将覆盖更新/清理并找出 full_clean 没有被调用时每个模型。
这开始变得令人头疼,我们更愿意让事情变得更简单、更明确。
【讨论】:
你能更明确地解释一下这部分吗? “第二个问题是,如果您有复杂的业务逻辑 [...],您可能应该在业务逻辑中进行验证,而不是深入模型进行验证。”该业务逻辑将在哪里存在并从哪里调用?你的意思是序列化器应该在验证期间调用一些业务逻辑吗?似乎在这个主题上有many opinions,这对于新的 Django / DRF 用户来说是不直观的。 “该业务逻辑将在哪里存在并从哪里调用?”在 MVC 中,它将在控制器中调用(在 django 中查看)。当您有复杂的逻辑(例如处理实时库存的商店)时,有时最好将库存计算留给业务层并让该层进行自己的验证。然后,序列化程序将只执行基本检查。已经写了一些关于此的想法(dabapps.com/blog/django-models-and-encapsulation)。请注意,这是 DRF 所做的设计选择。 嗨@Linovia - 仅供参考,这是否在 DRF 的文档中突出显示? 不,不是。这是与 Tom 聊天后的解释,以及在问题跟踪器上回答问题时用作指南的内容。以上是关于为啥 Django Rest Framework 不鼓励模型级别验证?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Django REST Framework 提供不同的身份验证机制
为啥 Django Rest Framework 不鼓励模型级别验证?
为啥我的 Django REST Framework 视图集 URL 没有解析?
Django Rest Framework - 为啥在尝试使用不正确的凭据登录用户时返回 200 状态码?
为啥从 django rest 框架返回的 JSON 在响应中有正斜杠?
Django-rest-framework 和 django-rest-framework-jwt APIViews and validation Authorization headers