Python - Django

Serializer & ModelSerializer

2017-11-01  本文已影响63人  廖马儿

初级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

上一篇 下一篇

猜你喜欢

热点阅读