[Django] rest framwork(一):序列化

rest framework概述

Django rest framework是一套基于Django的REST框架,是一个用于构建Web API的功能强大且灵活的工具包。

安装

$ pip install djangorestframework

如果没有安装Python,则需要安装Python和Django:

$ sudo apt-get install python3.6
$ sudo apt-get install python3-pip
$ pip install Django

一.序列化和反序列化

概述

序列化,是指将复杂的数据类型,如QuerySet和Model转换成Python基本数据类型,从而在Http响应时可以轻易被JSON,xml等其他的内容类型渲染。
反序列化,和序列化相反,是指将Http请求中传入的数据转换成复杂的数据类型,从而保存在数据库中。
在rest framework中,序列化操作类似于Django中的Form和Model类,同时rest框架提供了两个用于序列化的类:

  • Serializer:进行序列化的通用方式;
  • ModelSerializer:为处理Model实例和Queryset的序列化程序提供了有用的快捷方式。

使用时需要导入对应模块:

from rest_framework import serializers

一般序列化

Serializer定义格式如下:

from rest_framework import serializers

class CommentSerializer(serializers.Serializer):
    # 指定要序列化的字段
    email = serializers.EmailField()
    content = serializers.CharField(max_length=200)
    created = serializers.DateTimeField()
    # 用于反序列化时创建一个Model实例
    def create(self, validated_data):
        return Comment(**validated_data)
    # 用于反序列化时更新一个Model实例
    def update(self, instance, validated_data):
       # ...
       instance.email = validated_data.get('email',instance=emial)
       # ...
       return instance

先来看看在REST框架中如何序列化一个Model:

  • step1.创建一个model:
from django.db import models

class Student(models.Model):
    name = models.CharField(max_length=40)
    age = models.IntegerField()
    number = models.IntegerField(unique=True)
    date = models.DateField()
  • step2.创建一个序列化类:
    在app/下创建serializer.py文件
from rest_framework import serializers
from .models import Student

class StudentSerializer(serializers.Serializer):
    # 定义要序列化的字段
    name = serializers.CharField(read_only=True)
    age = serializers.IntegerField(read_only=True)
    number = serializers.IntegerField(read_only=True)
    date = serializers.DateField(read_only=True)

    # 在save()调用时生成一个Student对象
    def create(self, validated_data):
        # 会将生成的实例保存到数据库
        return Student.objects.create(**validated_data)

    # 在save()调用时更新Student对象
    def update(self, instance, validated_data):

        instance.name = validated_data.get('name', instance.name)
        instance.age = validated_data.get('age', instance.age)
        instance.number = validated_data.get('number', instance.number)
        instance.date = validated_data.get('date', instance.date)
        instance.save()  #确保保存在数据库
        return instance

这个序列化类中有两部分:

1.定义了要进行序列化的字段;
2.定义了当serializer.save()时用于生成Model对象的create()和update()方法。

  • step3.在Django shell下进行序列化测试
>>> from snippets.models import Student
>>> from snippets.serializers import StudentSerializer
>>> stu = Student(name='zhangsan',age=21,number=1,date='2018-4-23')
>>> stu.save()
>>> serializer = StudentSerializer(stu)
>>> serializer.data
{'name': 'zhangsan', 'age': 21, 'number': 1, 'date': '2018-4-23'}

现在将Student实例转换成了python本地数据类型(dict),接下来将本地数据类型转换为JSON数据:

>>> from rest_framework.renderers import  JSONRenderer
>>> from rest_framework.parsers import JSONParser
>>> content = JSONRenderer().render(serializer.data)
>>> content
b'{"name":"zhangsan","age":21,"number":1,"date":"2018-4-23"}'
>>> 

反序列化类似,第一步是将JSON形式数据转换为流的形式,并将流数据转化为python本地数据类型:

>>> from django.utils.six import BytesIO

>>> stream = BytesIO(content)
>>> data = JSONParser().parse(stream)
>>> data
{'name': 'zhangsan', 'age': 21, 'number': 1, 'date': '2018-4-23'}
>>> 

然后将python本地类型转换为实例:

>>> serializer = StudentSerializer(data=data)
>>> serializer.is_valid
>>> True
>>> serializer.validated_data
>>> serializer.save()

该例中是序列化了一个model对象,如果要序列化一个查询集,在设置serializer时添加一个参数:

>>> serializer = StudentSerializer(Student.objects.all(), many=True)
>>> serializer.data
>>> 

保存实例

create()方法和update()方法

Serializer中的create()update()方法用于创建生成一个Model实例,在使用Serializer时,如果要保存反序列化后的实例,则必须要实现这两方法之一,生成的实例则作为save()返回值返回。

save()方法

在调用serializer.save()时,则会创建或者更新一个Model实例,具体根据序列化类的实现而定,如:

# .save() will create a new instance.
serializer = StudentSerializer(data=data)

# .save() will update the existing `comment` instance.
serializer = StudentSerializer(comment, data=data)

校验数据

is_valid()方法

在我们将其他类型数据反序列化为一个Model对象时,在保存之间必须要进行校验,通过is_valid()方法进行,如果校验成功返回True,失败则返回False。

error

如果校验失败,则会将错误信息赋给该字典属性,如:

serializer = StudentSerializer(data=data)
if serializer.is_valid:
    serializer.save()
else:
    print(serializer.error)

属性

validated_data

表示校验的传入数据

data

返回原始数据,即序列化后的数据

使用ModelSerializers

ModelSerializers相比Serializer,提供了更快捷的方式对Model和QuerySet进行序列化操作,它自动创建了一个Serializer类,其中的字段与Model字段对应。ModelSerializer自动实现了两步骤:

1.根据Model自动检测并生成序列化的字段,不需要提前定义;
2.自动实现了create()方法和update()方法。

ModelSerializer定义格式如下:

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        # 指定一个Model,自动检测序列化的字段
        model = StudentSerializer
        fields = ('id', 'name', 'age', 'birthday')
model

该属性指定一个Model类,ModelSerializer会根据提供的Model类自动检测出需要序列化的字段,默认情况下,所有Model类中的字段将会映射到ModelSerializer类中相应的字段。对于任何的关系型字段将会映射到PrimaryKeyRelatedField字段上。

fields

如果不希望对Model中所有的字符进行序列化,可以在fields属性中显示指定要进行序列化的字段。

接下来使用ModelSerializer进行序列化:

  • step1.创建一个序列化类,继承于ModelSerializer:
class NewStudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ('id', 'name', 'age', 'number', 'date',)
  • step2.创建好之后,可以在django shell中打印查看:
>>> from snippets.serializers import NewStudentSerializer
>>> serializer = NewStudentSerializer()
>>> print(repr(serializer))
NewStudentSerializer():
    id = IntegerField(label='ID', read_only=True)
    name = CharField(max_length=40)
    age = IntegerField()
    number = IntegerField(validators=[<UniqueValidator(queryset=Student.objects.all())>])
    date = DateField()
>>> 

总结

使用ModelSerializer序列化时操作和一般序列化相同,对序列化的步骤再进行一次总结:

准备:
  • 1.序列化和反序列化针对于一个Model,因此要有一个model;
  • 2.在app/下创建一个序列化类,继承于from rest_framework import serializers中的Serializer或者ModelSerializer;
序列化:
  • 3.将model实例转换为python本地数据类型;
serializer = StudentSerializer(stu)
serializer.data
  • 4.将python本地类型转换为JSON;
from rest_framework.renderers import  JSONRenderer
content = JSONRenderer().render(serializer.data)
反序列化
  • 5.将JSON数据转换为一个流stream;
from django.utils.six import BytesIO
stream = BytesIO(content)
  • 6.将stream转换为python本地;
from rest_framework.parsers import JSONParser
data = JSONParser().parse(stream)
  • 7.python本地数据类型转换为model实例,并进行保存;
serializer = StudentSerializer(data=data)
serializer.is_valid
serializer.save()

猜你喜欢

转载自blog.csdn.net/fightfightfight/article/details/80059024