django休息框架在验证后对数据进行了哪些转换?是否只在可能的情况下将字符串解析为int?
答案 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')])
所以:
答案 2 :(得分:0)
data
和validated_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
属性设置为