繁体   English   中英

Django Rest Framework序列化程序验证器始终为空

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM