1.REST Framework概述

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

RESTful 简述

Representational State Transfer(REST),是一种架构样式,定义了一套用于创建WEB服务的约束。当前WEB开发趋势就是前端层出不穷,为了保证一个后台同时适用于多个前端,需要一种统一的机制或API,而RESTful API是目前前后端分离的最佳实践。

为什么需要前后端分离?

  • PC,APP,Pad 等多端适应;
  • SPA开发模式流行(Single Page web Application);
  • 使得前后端开发职责清楚,提高开发效率高;
  • 避免了开发语言和模板语言的高度耦合和开发语言之间的依赖;

RESTful API特点

  • 轻量,直接通过HTTP协议,不需要额外的协议;
  • 面向资源,每一个URL代表一种资源,具有自解释性;
  • 数据描述简单,一般通过JSON、xml做数据通信;
  • 客户端根据不同的请求,通过不同的HTTP方法(get、post、delete、put),对服务器资源进行操作。

为什么要使用Django REST 框架而不是Django?

虽然Django中可以通过DTL(Django Template Language)来实现PC端的显示,但却无法支持如Android端、ios端。而且Django只能依赖DTL实现PC端的显示。

要实现一套后台适应多个前端,就必须使用前后端分离技术,因此就要使用RESTful API,而Django REST框架正是基于Django的RESTful API。

2.安装Django REST Framework

通过如下命令安装REST 框架:

pip install djangorestframework

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

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

 

3.序列化和反序列化

序列化,是指将复杂的QuerySet和Model类型转换成Python基本数据类型,从而将这些基本数据类型以JSON的形式响应给客户端。

反序列化则和序列化相反,是指将Http请求中传入的JSON数据转换成复杂的数据类型,从而保存在数据库中。

在REST Framework中,提供了多个用于序列化操作的类,但常用的也就如下两个:

  • Serializer:进行序列化基本的类;
  • ModelSerializer:继承于Serializer,内部实现了通用的序列化逻辑,其中包含了与Model字段对应的字段,可以快速对Model进行序列化。

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

from rest_framework import serializers

  

接下来我们就分别看看这两个序列化操作的类。

4.Serializer

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.创建对该Model进行序列化的类:

在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.定义了要进行序列化的字段;这些字段负责将Python类型转换成JSON类型,即序列化的过程;
  • 2.定义了当serializer.save()时用于生成Model对象的create()和update()方法,这两方法负责将JSON类型的数据转换成Python类型的数据,即反序列化的过程。

整个序列化类的实现就这么简单,接下来我们还需要对这个序列化类进行测试。

测试Serializer有两种方式,一种是在Django Shell下进行测试,还有一种就是直接创建一个View,通过http请求进行测试,如果掌握了如何创建view,那么请直接在View中进行吧!

Step3.在Django shell下进行序列化测试

使用python manage.py shell进入Django Shell中:

>>> from Students.models import Student  # 导入对应module
>>> from Students.serializers import StudentSerializer
>>> stu = Student(name='zhangsan',age=21,number=1,date='2018-4-23') #创建一个Model实例
>>> stu.save()   # 将该实例存入数据库
>>> serializer = StudentSerializer(stu)   #进行序列化
>>> serializer.data  # 查看序列化后的结果
{'name': 'zhangsan', 'age': 21, 'number': 1, 'date': '2018-4-23'}

现在将Student实例转换成了Python中的dict类型,接下来将dict类型转换为JSON数据:

>>> from rest_framework.renderers import  JSONRenderer  #JSONRenderer将数据渲染称JSON格式
>>> 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
>>> from rest_framework.parsers import JSONParser
>>> stream = BytesIO(content) # 将JSON数据转换为流的形式
>>> data = JSONParser().parse(stream) # JSONParser将解析流中的JSON数据,得到Python的类型数据
>>> data
{'name': 'zhangsan', 'age': 21, 'number': 1, 'date': '2018-4-23'} # 一个dict类型的数据
>>>

然后将Python本地类型转换为实例,保存在数据库中:

>>> serializer = StudentSerializer(data=data)
>>> serializer.is_valid() # 验证是否有效
>>> True
>>> serializer.save() # 将保存在数据库中

该例中是序列化了一个Model对象,如果要序列化由Model.objects.all()返回的一个QuerySet实例,在设置serializer时添加一个参数:

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

虽然这种方式略显麻烦,但对于初学者来说,掌握Django shell还是很有用的。
如果对View相关知识了解,那么可以非常方便的在View中通过Http请求进行验证,如下是通过GET请求和POST请求用于验证Serializer:

from rest_framework import views
from rest_framework.response import Response
from rest_framework import status
from . import models
from .serializers import StudentSerializer
# Create your views here. class show(views.APIView): def get(self, request):
"""
get方法处理GET请求
"""
try:
Student = models.Student.objects.all()
# Student是一个QuerySet,而不是一个Model对象,因此需要设置many=True
serializer = StudentSerializer(Student, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
except Student.DoesNotExist:
return Response(serializer.data, status=status.HTTP_404_NOT_FOUND) def post(self, request):
"""
post方法处理POST请求
"""
# request.data是请求体中经过解析后的数据
serializer = StudentSerializer(data=request.data)
if serializer.is_valid(): # 检验是否有效
serializer.save() # 将会调用Serializer中的create(),并保存在数据库中
# serializer.data是序列化后的原始数据
# rest_framework.status中定义了常见返回值,如404,200...
return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
ails/80059024

关于DRF的View相关部分会在之后的文章中详细总结。

5.Serializer的方法和属性

1.save()

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

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

2.create()、update()

Serializer中的create()和update()方法用于创建生成一个Model实例,在使用Serializer时,如果要保存反序列化后的实例到数据库,则必须要实现这两方法之一,生成的实例则作为save()返回值返回。方法属性validated_data表示校验的传入数据。

3. is_valid()

当反序列化时,在调用Serializer.save()之前必须要使用is_valid()方法进行校验,如果校验成功返回True,失败则返回False,同时会将错误信息保存到serializer.errors属性中。

4.data

serializer.data中保存了序列化后的数据。

5.errors

当serializer.is_valid()进行校验后,如果校验失败,则将错误信息保存到serializer.errors属性中。

6.Serializer中的Field

在定义Model时,我们通过models.<FieldName>获取了各种不同的字段,作为数据库中表的一个列。而在Serializer中,也需要通过`serializers.<FieldName>的形式获取对应Model的字段,用来在JSON数据和Python数据类型之间进行转换,此外还可以根据Field中传入的属性进行校验、设置默认值。以下对常用Serializer的Field进行整理。

使用时,需要导入所在模块:

from rest_framework import serializers

1.CharField

对应models.CharField,同时如果指定长度,还会负责校验文本长度。

max_length:最大长度;
min_length:最小长度;
allow_blank=True:表示允许将空串做为有效值,默认False;

2.EmailField

对应models.EmailField,验证是否是有效email地址。

3.IntegerField

对应models.IntegerField,代表整数类型

4.FloatField

对应models.FloatField,代表浮点数类型

5.DateTimeField

对应models.DateTimeField,代表时间和日期类型。

format='YYYY-MM-DD hh:mm':指定datetime输出格式,默认为DATETIME_FORMAT值。
需要注意,如果在 ModelSerializer 和HyperlinkedModelSerializer中如果models.DateTimeField带有auto_now=True或者auto_add_now=True,则对应的serializers.DateTimeField中将默认使用属性read_only=True,如果不想使用此行为,需要显示对该字段进行声明:

class CommentSerializer(serializers.ModelSerializer):
created = serializers.DateTimeField() class Meta:
model = Comment

6.FileField

对应models.FileField,代表一个文件,负责文件校验。

max_length:文件名最大长度;
allow_empty_file:是否允许为空文件;

7.ImageField

对应models.ImageField,代表一个图片,负责校验图片格式是否正确。

max_length:图片名最大长度;
allow_empty_file:是否允许为空文件;
如果要进行图片处理,推荐安装Pillow: pip install Pillow

8.HiddenField

这是serializers中特有的Field,它不根据用户提交获取值,而是从默认值或可调用的值中获取其值。一种常见的使用场景就是在Model中存在user_id作为外键,在用户提交时,不允许提交user_id,但user_id在定义Model时又是必须字段,这种情况下就可以使用HiddenField提供一个默认值:

class LeavingMessageSerializer(serializers.Serializer):

    user = serializers.HiddenField(
default=serializers.CurrentUserDefault()
)

6.serializers.Field中的公共参数

所谓公共参数,是指对于所有的serializers.<FieldName>都可以接受的参数。以下是常见的一些公共参数。

1.read_only

read_only=True表示该字段为只读字段,即对应字段只用于序列化时(输出),而在反序列化时(创建对象)不使用该字段。默认值为False。

2.write_only

write_only=True表示该字段为只写字段,和read_only相反,即对应字段只用于更新或创建新的Model时,而在序列化时不使用,即不会输出给用户。默认值为False。

3.required

required=False表示对应字段在反序列化时是非必需的。在正常情况下,如果反序列化时缺少字段,则会抛出异常。默认值为True。

4.default

给字段指定一个默认值。需要注意,如果字段设置了default,则隐式地表示该字段已包含required=False,如果同时指定default和required,则会抛出异常。

5.allow_null

allow_null=True表示在序列化时允许None作为有效值。需要注意,如果没有显式使用default参数,则当指定allow_null=True时,在序列化过程中将会默认default=None,但并不会在反序列化时也默认。

6.validators

一个应用于传入字段的验证函数列表,如果验证失败,会引发验证错误,否则直接是返回,用于验证字段,如:

username = serializers.CharField(max_length=16, required=True, label='用户名',
validators=[validators.UniqueValidator(queryset=User.objects.all(),message='用户已经存在')]) 

7.error_message

验证时错误码和错误信息的一个dict,可以指定一些验证字段时的错误信息,如:

mobile= serializers.CharField(max_length=4, required=True, write_only=True, min_length=4,
label='电话', error_messages={
'blank': '请输入验证码',
'required': '该字段必填项',
'max_length': '验证码格式错误',
'min_length': '验证码格式错误',
})

7.style

一个键值对,用于控制字段如何渲染,最常用于对密码进行密文输入,如:

 password = serializers.CharField(max_length=16, min_length=6, required=True, label='密码',
error_messages={
'blank': '请输入密码',
'required': '该字段必填',
'max_length': '密码长度不超过16',
'min_length': '密码长度不小于6', },
style={'input_type': 'password'}, write_only=True) 

9.label

一个简短的文本字串,用来描述该字段。

10.help_text

一个文本字串,可用作HTML表单字段或其他描述性元素中字段的描述。

11.allow_blank

allow_blank=True 可以为空    设置False则不能为空

12.source

source='user.email'(user表的email字段的值给这值)  设置字段值  类似default   通常这个值有外键关联属性可以用source设置

13.validators

验证该字段跟  单独的validate很像

UniqueValidator 单独唯一

validators=[UniqueValidator(queryset=UserProfile.objects.all())

UniqueTogetherValidator: 多字段联合唯一,这个时候就不能单独作用于某个字段,我们在Meta中设置。

validators = [UniqueTogetherValidator(queryset=UserFav.objects.all(),fields=('user', 'course'),message='已经收藏')]

14.error_messages

错误消息提示

error_messages={
"min_value": "商品数量不能小于一",
"required": "请选择购买数量"
})

7.ModelSerializers

ModelSerializers继承于Serializer,相比其父类,ModelSerializer自动实现了以下三个步骤:

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

使用ModelSerializer方式如下:

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

相比于Serializer,可以说是简单了不少,当然,有时根据项目要求,可能也会在ModelSerializer中显示声明字段,这些在后面总结。

model

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

fields

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

一,Serializer和ModelSerializer的更多相关文章

  1. Django REST Framework(一) Serializer和ModelSerializer

    REST Framework概述 Django REST framework是一套基于Django的REST框架,是一个用于构建Web API的功能强大且灵活的工具包. 1.RESTful 简述Rep ...

  2. Django Restful Framework (二): ModelSerializer

    时常,你需要对django model 的实例进行序列化.ModelSerializer 类提供了一个捷径让你可以根据 Model 来创建 Serializer. ModelSerializer 类和 ...

  3. Serializers 序列化组件——ModelSerializer详解

    前面学习Serializers用法时,发现所有的序列化都与我们的模型紧密相关. django_restframework也给我提供了跟模型紧密相关的序列化器——ModelSerializer. 它会根 ...

  4. drf框架 - 序列化组件 | ModelSerializer (查,增,删,改)

    ModelSerializer 序列化准备: 配置 settings.py # 注册rest_framework框架 INSTALLED_APPS = [ ... 'rest_framework' ] ...

  5. rest framework serializer

    串行器 扩大串行的用处是什么,我们想地址.然而,这不是一个简单的问题,它会采取一些严重的设计工作. -罗素基思-马吉,Django的用户组 串行器允许诸如查询集和模型实例复杂的数据转换为原生的Pyth ...

  6. drf之序列化组件(一):Serializer

    序列化组件:Serializer.ModelSerializer.ListModelSerializer Serializer  偏底层  ModelSerializer       重点  List ...

  7. django rest framework serializers

    django rest framework serializers序列化   serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用:- 将qu ...

  8. django rest framework serializers序列化

    serializers是将复杂的数据结构变成json或者xml这个格式的 serializers有以下几个作用: - 将queryset与model实例等进行序列化,转化成json格式,返回给用户(a ...

  9. rest_framework框架的认识

    它是基于Django的,帮助我们快速开发符合RESTful规范的接口框架. 一  路由 可以通过路由as_view()传参 根据请求方式的不同执行对应不同的方法 在routers模块下 封装了很多关于 ...

随机推荐

  1. kotlin的安装(一)

    1.下载Kotlin Compiler Kotlin 命令行环境主要依赖就是Kotlin Compiler,目前最新版本是 1.1.2-2.其下载链接是:https://github.com/JetB ...

  2. 关于chrome控制台警告:Synchronous XMLHttpRequest on the main thread

    Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to th ...

  3. OSB格式(REST)转化(XML到JSON,JSON到XML)

    OSB转换项目操作手册 新建一个OSB项目 建立以下文件夹,以便更规范的管理工程 一.XML转JSON 1.导入wsdl文件 1)右键wsdl文件夹,选择import选项 2)在弹出框中选择Servi ...

  4. java 日期排序。。。。

    Collections.sort(list, new Comparator<Map<Object, Object>>() { public int compare(Map< ...

  5. mongodb对数据的增删改查

    数据类型 下表为MongoDB中常用的几种数据类型: Object ID:文档ID String:字符串,最常用,必须是有效的UTF-8 Boolean:存储一个布尔值,true或false Inte ...

  6. 用网线直连的两台PC上的虚拟机通过网线通信的配置

    Configure the ROS Networks: Quick Reference: http://blog.csdn.net/sonictl/article/details/46986565#t ...

  7. 使用DolphinPHP的框架中的excel插件导入数据

    直接上函数吧 public function importfile() { if ($this->request->isPost()) { if($_POST['files']) { Cu ...

  8. <转载>http头 http://www.cnblogs.com/meil/archive/2007/03/06/665843.html

    HTTP(HyperTextTransferProtocol)是超文本传输协议的缩写,它用于传送WWW方式的数据,关于HTTP协议的详细内容请参考RFC2616.HTTP协议采用了请求/响应模型.客户 ...

  9. JS中点击事件冒泡阻止

    JS中点击事件冒泡阻止 解析: 一个div层'out',内含有一个div层'in'.如下: 两个层都绑定了点击事件,但是点击in层的时候,点击事件会出现冒泡现象,同时也会触发out层的点击事件. 但是 ...

  10. Mp4 to Img

    # -*- coding: utf-8 -*- """ Created on Thu May 3 16:51:50 2018 """ # 录 ...