博客五部曲之三 - 博客RESTful


1642 浏览 5 years, 9 months

5 Python Shell中序列号对象

版权声明: 转载请注明出处 http://www.codingsoho.com/

Python Shell中序列号对象

这节我们将会在shell中运行Serializer,让你更好的理解它在python中怎么工作的。

(env) E:\Computer\virtualenv\iblog\csblog>python manage.py shell
Python 2.7.10 (default, May 23 2015, 09:40:32) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from posts.models import Post
>>> from posts.api.serializers import PostSerializer
>>> obj = Post.objects.first()
>>> obj
<Post: new post 11>
>>> obj.id
1
>>> obj_data = PostSerializer(obj)
>>> obj_data
PostSerializer(<Post: new post 11>):
    title = CharField(max_length=120)
    slug = SlugField(max_length=50, validators=[<UniqueValidator(queryset=Post.objects.all())>])
    publish = DateField()
>>> obj_data.data
{'slug': u'new-post', 'publish': '2019-04-18', 'title': u'new post 1'}

初始化PostSerializer

用Post对象初始化PostSerializer,可以打印出对应的fields里的data

>>> data = {
...     "title" : "hi, there",
...     "content": "new content",
... }
>>> new_item = PostSerializer(data=data)
>>> new_item.data
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "E:\Computer\virtualenv\iblog\env\lib\site-packages\rest_framework\serializers.py", line 560, in data
    ret = super(Serializer, self).data
  File "E:\Computer\virtualenv\iblog\env\lib\site-packages\rest_framework\serializers.py", line 258, in data
    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.
>>> new_item.initial_data
{'content': 'new content', 'title': 'hi, there'}

data validation

如果自定义字典来初始化,不能直接调用data属性,从出错提示看我们需要先调用is_valid来验证然后才能访问data变量,但是我们可以随时打印initial_data,这个就是我们初始化传进去的值。
这些操作跟form非常像。data类似form的cleaned_data

下面我们写一段代码来测试PostSerializer的验证过程,跟form的验证非常类似。

>>>
>>> new_item = PostSerializer(data=data)
>>> if new_item.is_valid():
...     new_item.save()
... else:
...     print new_item.errors
...
{'slug': [ErrorDetail(string=u'This field is required.', code=u'required')], 'publish': [ErrorDetail(string=u'This field is required.', code=u'required')]}

传进去的data没有slug和publish字段,所以报错字段缺失。

>>>
>>> data = {
...     "title" : "hi, there",
...     "slug": "new content",
... }
>>>
>>> new_item = PostSerializer(data=data)
>>> if new_item.is_valid():
...     new_item.save()
... else:
...     print new_item.errors
...
{'slug': [ErrorDetail(string=u'Enter a valid "slug" consisting of letters, numbers, underscores or hyphens.', code=u'invalid')], 'publish': [ErrorDetail(string=u'This field is requ
ired.', code=u'required')]}

添加slug字段,但是格式不正确,它同样针对格式进行验证,报错slug格式不匹配。

>>>
>>> data = {
...     "title" : "hi, there",
...     "slug": "new-content",
...     "publish": "2018-02-02"
... }
>>>
>>> new_item = PostSerializer(data=data)
>>> if new_item.is_valid():
...     new_item.save()
... else:
...     print new_item.errors
...
<Post: hi, there19>
>>> new_item.data
{'slug': u'new-content', 'publish': '2018-02-02', 'title': u'hi, there'}

按照fields定义的字段赋值data传递给PostSerializer,验证通过。New_item.data打印出完整内容。

>>> new_item.id
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'PostSerializer' object has no attribute 'id'

我们调用一下new_item.id来访问ID,报错属性不存在。所以它返回的只是序列化对象,而不是数据库存储。