[英]Django Rest Framework serializer validator always empty
我正在尝试打印django rest框架中的验证器列表,但是当我打印出来时,它似乎总是空的。
这是代码的一部分
class AccountViewSet(viewsets.ModelViewSet):
lookup_field = 'username'
queryset = Account.objects.all()
serializer_class = AccountSerializer
def create(self, request):
serializer = self.serializer_class(data=request.data)
# this always return []
print serializer.validators
这是违反直觉的,因为当我在request.data
测试无效数据时,该代码显然会运行验证程序,因为is_valid()
返回错误(如文档所示)。 因此,我可以观察到验证器生效但无法打印出来是没有意义的。 有人可以指出我所缺少的吗?
谢谢
为什么您的情况下serializer.validators
返回[]
?
发生这种情况的原因是,在创建序列化程序的实例时,尚未将validators
参数传递给序列化程序。 如果您传递了validators
参数,则将serializer._validators
设置为该值。 然后,如果您检查serializer.validators
,它将为您提供通过的验证器列表。
例如:
In [1]: serializer = SomeSerializer(data=some_data, validators=[validator1, validator2])
In [2]: serializer.validators
Out [2]: [validator1, validator2] # gives the list of validators
默认情况下,如果在访问serializer.validators
时未传递任何验证器,则返回[]
。
供参考的源代码:
现在, BaseSerializer
继承自Field
类,该类调用其__init__()
。
class BaseSerializer(Field):
def __init__(self, instance=None, data=empty, **kwargs):
...
super(BaseSerializer, self).__init__(**kwargs)
在这里, default_validators
是一个空列表[]
。
class Field(object):
default_validators = [] # an empty list by default
default_empty_html = empty
initial = None
def __init__(self, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None,
label=None, help_text=None, style=None,
error_messages=None, validators=None, allow_null=False):
...
# Here, it checks if validators argument was passed when creating the serializer instance
# If you have passed, then `.validators` will be set to that value.
if validators is not None:
self.validators = validators[:]
...
@property
def validators(self):
if not hasattr(self, '_validators'):
# This will be executed as there was no validators passed in kwargs
self._validators = self.get_validators()
return self._validators
@validators.setter
def validators(self, validators):
self._validators = validators
def get_validators(self):
return self.default_validators[:] # returns empty list
为什么您的代码显示无效数据错误呢?
这是因为字段级验证程序导致了该错误。 您的序列化程序级别的验证程序是[]
但是有些字段级别的验证程序正在引发无效数据错误。
要查看字段级验证器,可以执行print repr(serializer)
。
从http://www.django-rest-framework.org/api-guide/validators/
REST框架中的验证
Django REST框架序列化程序中的验证与Django的ModelForm类中的验证工作方式稍有不同。
使用ModelForm,验证部分在表单上执行,部分在模型实例上执行。 使用REST框架,验证完全在序列化程序类上执行。 由于以下原因,这是有利的:
- 它引入了适当的关注点分离,使您的代码行为更加明显。
- 在使用快捷方式ModelSerializer类和使用显式Serializer类之间进行切换很容易。 用于ModelSerializer的任何验证行为都易于复制。
- 打印序列化程序实例的
repr
将准确显示其适用的验证规则。 在模型实例上没有调用任何额外的隐藏验证行为。使用ModelSerializer时,所有这些都会自动为您处理。 如果要改为使用Serializer类,则需要显式定义验证规则。
例
作为REST框架如何使用显式验证的示例,我们将使用一个简单的模型类,该类具有一个具有唯一性约束的字段。
class CustomerReportRecord(models.Model): time_raised = models.DateTimeField(default=timezone.now, editable=False) reference = models.CharField(unique=True, max_length=20) description = models.TextField()
这是一个基本的ModelSerializer,可用于创建或更新CustomerReportRecord实例:
class CustomerReportSerializer(serializers.ModelSerializer): class Meta: model = CustomerReportRecord
如果我们使用manage.py shell打开Django shell,我们现在可以
>>> from project.example.serializers import CustomerReportSerializer >>> serializer = CustomerReportSerializer() >>> print(repr(serializer)) CustomerReportSerializer(): id = IntegerField(label='ID', read_only=True) time_raised = DateTimeField(read_only=True) reference = CharField(max_length=20, validators=[<UniqueValidator(queryset=CustomerReportRecord.objects.all())>]) description = CharField(style={'type': 'textarea'})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.