如何提供封装在字段类中的自定义,模型级别,字段验证?
我正在玩两个JSONField实现,(first,second)。我正在为我的应用程序使用Django和Django REST框架的组合。我在表单级别上没有做任何事情,只有公开该模型的Web API。
理想情况下,我想在一个地方编写此验证,并在串行器级别+模型级别上运行(就像我传递validators=[x]
时)。我不能使用通常的validators=[x]
,因为我需要允许blank=True
,但也要验证空白值类型:|。
我有一个用例,我想验证JSONField
的内容(键,值的类型)。使用validictory,我可以这样做:
self.full_clean()
save()
clean()
并在那里进行验证但是,我 想要做的是:将此验证添加到JSONField
的子类中。我想留下尽可能多的父Field
课来做这件事。到目前为止,我有:
from django.db import models
from jsonfield import JSONField
class myValidatorField(JSONField):
def validate(self, *args, **kwargs):
# do some validation here
super(myValidatorField, self).validate(*args, **kwargs)
class MyModel(models.Model):
jsonstuff = myValidatorField(default=[])
def save(self, *args, **kwargs):
self.full_clean()
super(MyModel, self).save(*args, **kwargs)
然而,我无法让它发挥作用。这个validate()
方法不会针对second实施运行,而对于first,它会运行4次。
混淆。
答案 0 :(得分:1)
我最终得到了这个代码,似乎可以解决这个问题。
仅供参考,在我的用例中,我必须实现一个自定义的django rest框架异常处理程序来捕获我的所有模型级别ValidationError
错误并将其转换为网络400
错误。
# fields.py
import validictory
from jsonfield import JSONField
class JSONSchemaField(JSONField):
"""A field that will ensure the data entered into it is valid JSON *and*
internally validate to a JSON schema of your choice."""
def __init__(self, *args, **kwargs):
self.schema = kwargs.pop('schema', {})
super(JSONSchemaField, self).__init__(*args, **kwargs)
def clean(self, raw_value, model_instance):
try:
validictory.validate(raw_value, self.schema)
except (validictory.FieldValidationError,
validictory.SchemaError,
validictory.validator.RequiredFieldValidationError) as err:
raise ValidationError(err)
return super(JSONSchemaField, self).clean(raw_value, model_instance)
# mixins.py
class ModelValidationMixin(object):
"""Django currently doesn't force validation on the model level
for compatibility reasons. We enforce here, that on each save,
a full valdation run will be done the for model instance"""
def save(self, *args, **kwargs):
self.full_clean()
super(ModelValidationMixin, self).save(*args, **kwargs)
# models.py
class MyModel(ModelValidationMixin):
json = JSONSchemaField(default='[]', schema=SCHEMA)