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()