美文网首页Python - Django
Serializer & ModelSerializer

Serializer & ModelSerializer

作者: 廖马儿 | 来源:发表于2017-11-01 10:57 被阅读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

    相关文章

      网友评论

        本文标题:Serializer & ModelSerializer

        本文链接:https://www.haomeiwen.com/subject/tcnbpxtx.html