【发布时间】:2018-06-21 13:15:38
【问题描述】:
我有一个特定的模型,我想对其执行自定义验证。我想保证在创建新实例时始终存在至少一个标识符字段,这样就不可能在没有这些字段之一的情况下创建实例,尽管没有特别需要单独的字段。
from django.db import models
class Security(models.Model):
symbol = models.CharField(unique=True, blank=True)
sedol = models.CharField(unique=True, blank=True)
tradingitemid = models.Charfield(unique=True, blank=True)
无论原始数据来自何处(例如,API 帖子或从其他来源(如 .csv 文件)获取此数据的内部函数),我都想要一种干净、可靠的方法。
我知道我可以覆盖模型的 .save() 方法并执行验证,但最佳实践表明 here 建议在 .save() 方法中引发验证错误是一个坏主意,因为视图只会返回 500响应而不是向发布请求返回验证错误。
我知道我可以使用 Django Rest Framework 为该模型定义一个带有 validator 的自定义序列化程序来验证数据(这对于创建对象的 ModelViewSet 来说是一个很好的解决方案,我可以保证这个序列化程序是每次使用)。但是这种数据完整性保证只在那个 API 端点上是好的,然后就像开发人员记住每次在代码库的其他地方创建对象时都使用该序列化程序一样好(对象可以在整个代码库中从源之外的源创建Web API)。
我也熟悉 Django 的.clean() and .full_clean() methods。这些似乎是完美的解决方案,但它再次依赖于开发人员始终记得调用这些方法——这种保证与开发人员的记忆力一样好。我知道在使用 ModelForm 时会自动调用这些方法,但同样,对于我的用例模型,也可以从 .csv 下载中创建——我需要一个通用的保证,这是最佳实践。我可以将 .clean() 放在模型的 .save() 方法中,但是这个 answer(以及帖子中的相关 cmets 和链接)似乎使这种方法引起争议,并且可能是一种反模式。
是否有一种干净、直接的方法可以保证如果没有以下三个字段之一,该模型永远不会被保存:1. 不会通过视图引发 500 错误,2. 不依赖于开发人员在创建对象时在整个代码库中明确使用正确的序列化程序,以及 3. 不依赖于将 .clean() 调用侵入模型的 .save() 方法(看似反模式)?我觉得这里必须有一个干净的解决方案,而不是在序列化程序中进行一些验证,一些在 .clean() 方法中,破解 .save() 方法来调用 .clean() (它会通过 ModelForms 的保存被调用两次)等...
【问题讨论】:
标签: python django rest validation django-rest-framework