django rest框架中的数据和验证数据之间有什么区别?

时间:2017-02-02 11:11:42

标签: django django-rest-framework

django休息框架在验证后对数据进行了哪些转换?是否只在可能的情况下将字符串解析为int?

3 个答案:

答案 0 :(得分:7)

DESERIALIZING

数据是Serializer的输入 例如

serializer = CommentSerializer(data={'email': 'foobar', 'content': 'baz'})

如您所见,电子邮件无效,因此以下规则适用(来自官方文件)

  

反序列化数据时,您始终需要先调用is_valid()   尝试访问经过验证的数据,或保存对象实例

serializer.is_valid()

如果您尝试反序列化的data有效#True,那么您可以访问经过验证的数据

serializer.validated_data

ADDITION

验证后没有数据转换,它只检查您的数据是否有效,如果发生任何验证错误,.errors属性将包含表示结果错误消息的字典。

一个很好的例子就是你进行现场验证

class CommentSerializer(serializers.Serializer):
    title = serializers.CharField(max_length=100)

    def validate_title(self, value):
        if 'django' not in value.lower():
           raise serializers.ValidationError("Title is not about Django")
        return value
每次调用validate_title时都会调用

.is_valid(),因为您可以看到它只检查标题是否与django相关,如果为True,则返回此标题中返回的值,否则引发ValidationError。这里不改变数据

答案 1 :(得分:7)

您可以在CommentSerializer.validate_content方法中自定义数据:

这是你的序列化器:

class CommentSerializer(serializers.Serializer):
    email=serializers.EmailField()
    content=serializers.CharField()
    def validate_content(self,value):
        #If content is 'baz' returns 'foo'
        if value and value == "baz":
            return "foo"
        return value

所以: 让我们尝试使用错误的值(电子邮件)

>>> serializer = CommentSerializer(data={'email': 'foobar', 'content': 'baz'})

>>> serializer.data
Traceback (most recent call last):
    raise AssertionError(msg)
AssertionError: When a serializer is passed a `data` keyword argument you must call `.is_valid()` before attempting to access the serialized `.data` representation.
You should either call `.is_valid()` first, or access `.initial_data` instead.

>>> serializer.initial_data
{'content': 'baz', 'email': 'foobar'}

>>> serializer.validated_data
Traceback (most recent call last):
   raise AssertionError(msg) 
AssertionError: You must call `.is_valid()` before accessing `.validated_data`.

>>> serializer.is_valid()
False

>>> serializer.data
{'content': 'baz', 'email': 'foobar'}

>>> serializer.validated_data
{}

>>> serializer.errors
{'email': [u'Enter a valid email address.']}

现在让我们试试正确的值

>>> serializer2 = CommentSerializer(data={'email': 'foobar@email.it', 'content': 'baz'})  
>>> serializer2.is_valid()
True

>>> serializer2.initial_data
{'content': 'baz', 'email': 'foobar@email.it'}
>>> serializer2.errors
{}

>>> serializer2.data
{'content': u'foo', 'email': u'foobar@email.it'}

>>> serializer2.validated_data
OrderedDict([(u'email', u'foobar@email.it'), (u'content', u'foo')])

所以:

  • 数据:是一个字典,您只能在 is_valid()之后才能看到它(您只能看到未经验证的值)
  • validated_data 是一个OrderedDict,您只能在 is_valid()&& is_valid()== True

答案 2 :(得分:0)

datavalidated_data 不一定总是相同的。 例如:

class UserSerializer(serializers.Serializer):
    name = serializers.CharField()
    phone = serializers.CharField(required=False, allow_null=True)

我们可以获得不同的数据:

>>> user = UserSerializer(data={'name': 'Foo'})
>>> user.is_valid()
True
>>> user.data
{'name': 'Foo', 'phone': None}
>>> user.validated_data
{'name': 'Foo'}

基于BaseSerializer internal code,只要验证了序列化程序,data属性就是self.to_representation(self.validated_data)

elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
    self._data = self.to_representation(self.validated_data)

在这种情况下,to_representation internal code将这些情况设置为None


由于此行为,我建议在validated_data上使用data。如果您将data与这样的序列化程序一起使用,并根据data显式地将属性设置为对象,则可以将初始数据中不存在的None属性设置为