初级Serilaizer和ModelSerializer:
Serializer
作用:
可通过DRF的Serializer,来将数据保存到数据库中。
我们甚至都可以不用模型去保存了。
也就是与Form功能很像。
Serializer这里的功能可以相当于django的 form功能,也可以完成序列化为json的功能。
实例:
# serializers.py
from rest_framework import serializers
from ..models import Goods
class GoodsSerializer(Serializer):
name = serializers.CharField(required=True, max_length=100)
click_num = serializers.IntegerField(default=0)
# views.py
from rest_framework.views import APIView
from rest_framework.response import Response # 这个是DRF的Response
from .serializers import GoodsSerializer
class GoodsListAPIView(APIView):
def get(self, request, format=None):
goods = Goods.objects.all()[:10]
goods_sl = GoodsSerializer(goods, many=True) # 序列化为数组 注意多个
return Response(goods_sl.data) # goods_sl.data就是序列化之后的数据,
# 这里也没有添加其他的状态
图片.png
比如DRF 的 serializer,可以自动完善ImageField的路径。
validated_data
可以重写Serializer中的create方法:
图片.png注意参数validated_data
,这里会把name,click_num,goods_front这些seriliazer字段放入validated_data
字典中。
如果这个序列类作为前端添加的接口的话,那么这可以:
1)通过Serializer去验证前端json传递过来的body。
request.data # 就是DRF的request.data
2)保存数据到数据库中。
ModelSerializer
更加方便。自己会去映射。这样写起来更加简单。
class GoodsSerializer(Serializer):
class Meta:
model = Goods
fields = "__all__"
Serializer嵌套Serializer
图片.png** DRF status**
HTTP_200_OK 一般是GET请求的一个响应。
HTTP_201_CREATED 一般是POST请求的一个响应。
** 设置分页 **
系统设置分页.png也可以单独设置分页。
图片.png
注意:count是总共的个数。
官方链接:
http://www.django-rest-framework.org/api-guide/serializers/
ModelSerializer 比Serializer封装好了一层,直接自己生成的create和update,不用覆盖了,其实推荐用这个,毕竟Serializer封装的很低级,既然用django,就要用好点的。
Serializer本身就是一种字段。
翻译:
Serializers允许复杂的数据,例如:querysets和model实例转为能被轻易渲染进入JSON,XML或者其他内容形式的天然的Python数据类型。Serializers也体用了反序列化deserialization。
Serializers在REST framework中工作起来很像Django的Form和ModelForm类。
restful framework提供的Serializer类给我们了强大的,通用的方式去控制responses,以及ModelSerializer类提供了更加好的方式去应付model实例和querysets。
定义Serializers
让我们从创建一个简单的python对象开始:
from datetime import datetime
class Comment(object):
def __init__(self, email, content, created=None):
self.email = email
self.content = content
self.created = created or datetime.now()
comment = Comment(email='leila@example.com', content='foo bar')
我们将会声明一个serializer,我们可以使用它去序列化和反序列化Comment对象。
声明一个serializer看起来很类似于声明一个form:
from rest_framework import serializers
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
序列化对象
我们现在可以使用CommentSerializer去序列化一个comment,或者列表化很多comments。
还是一样,使用Serializer很像使用一个Form类:
serializer = CommentSerializer(comment)
serializer.data
# {'email': 'leila@example.com', 'content': 'foo bar', 'created': '2016-01-27T15:17:10.375877'}
注意:data是一个字典。
此时,我们已经将model实例转换为了python天然的数据类型。我们将data写入到json中结束实例化步骤(上面都是在python shell中做的,没有写>>>注意下):
>>> from rest_framework.renderers import JSONRenderer
>>> json = JSONRenderer().render(serializer.data)
>>> json
'{"email":"leila@example.com","content":"foo bar","created":"2017-10-31T18:07:45.939182"}'
反序列化对象
反序列化也是类似的,首先我们应该解析流到python的天然的数据类型中:
from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser
stream = BytesIO(json)
data = JSONParser().parse(stream)
data
# {u'content': u'foo bar', u'email': u'leila@example.com', u'created': u'2017-10-31T18:07:45.939182'}
serializer = CommentSerializer(data=data) # 这个原来是反序列化
serializer.is_valid()
# True
serializer.validated_data
保存instances
如果我们想能够返回完整的基于合法数据的对象,我们需要实现create()
和update()
方法,例如:
class CommentSerializer(serializers.Serializer):
email = serializers.EmailField()
content = serializers.CharField(max_length=200)
created = serializers.DateTimeField()
def create(self, validated_data):
return Comment(**validated_data)
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
return instance
如果你的对象对应的是Django的models,那么你也想确保这些方法将会保存到数据库中。比如,如果Comment
是一个Django模型,那么这些方法将会是这样:
def create(self, validated_data):
return Comment.objects.create(**validated_data)
def update(self, instance, validated_data):
instance.email = validated_data.get('email', instance.email)
instance.content = validated_data.get('content', instance.content)
instance.created = validated_data.get('created', instance.created)
instance.save()
return instance
现在当反序列化数据的时候,我们需要调用save()
去返回一个对象实例:
comment = serializer.save()
调用save()
将会创建一个新的实例,或者更新一个已经存在的实例:
# .save() will create a new instance.
serializer = CommentSerializer(data=data)
# .save() will update the existing `comment` instance.
serializer = CommentSerializer(comment, data=data)
create()
和update()
方法都是可选的,你可以实现一种也可以都实现,或者都不识闲,取决于你的serializer的类的使用情况。
传递额外的属性到save()
方法中:
有的时候你想你的view代码能够注入额外的数据当在保存实例的时候。这些额外的数据可能包含的信息比如:当前的user,当前的时间,或者其他的非request数据。
你也可以像下面这样去调用save()方法:
serializer.save(owner=request.user)
任何的额外的关键字参数将会被包含进validated_data
参数中当create()
或者update()
被调用的时候。
直接覆盖save()
方法:
有的时候,create()
和update()
方法的名字可能是有含义的,比如,在一个contact form中,我们可能不是创建新的实例,而是发送邮件或者其他的信息。
在这样的情况下你可能不会选择直接去覆盖save()
方法,
太多了
http://www.django-rest-framework.org/api-guide/serializers/#passing-additional-attributes-to-save
网友评论