10. REST & ECharts¶
django-restful是一个为django提供的,让django能够方便提供API接口服务的第三方框架。
有了RESTful设计,服务器程序就能更好的进行前后端分离设计,服务器部分只负责处理数据,一般采用json格式, 而前端只需要负责展示部分即可。
前后端分离设计可以看作是把django中的模板部分单独独立出来,可以使用任何前端技术, 而后端只负责处理数据和数据交互即可。
- 虚拟环境下安装:
- pip install djangorestframework
- 测试发送端:
- 参看文章
10.1. RESTful概述¶
一种软件架构风格,设计风格而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交互 类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。
2000 年 Roy Fielding 的博士论文中,他是 HTTP 规范的主要编写者之一。
10.2. 设计指南¶
使用名词表示资源
关注请求头
- GET:
- 请求指定的页面信息,并返回实体主体
- GET请求请提交的数据放置在HTTP请求协议头中
- GET方法通过URL请求来传递用户的输入,
- GET方式的提交你需要用Request.QueryString来取得变量的值。
- GET方法提交数据,可能会带来安全性的问题,数据被浏览器缓存。
- GET请求有长度限制。
- HEAD:
- 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。
- POST:
- 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。
- POST请求可能会导致新的资源的建立和/或已有资源的修改。
- POST方式提交时,你必须通过Request.Form来访问提交的内容
- PUT:
- 从客户端向服务器传送的数据取代指定的文档的内容。
- DELETE:
- 请求服务器删除指定的页面。
- DELETE请求一般返回3种码
- 200(OK): 删除成功,同时返回已经删除的资源。
- 202(Accepted): 删除请求已经接受,但没有被立即执行(资源也许已经被转移到了待删除区域)。
- 204(NoContent): 删除请求已经被执行,但是没有返回资源(也许是请求删除不存在的资源造成的)。
- CONNECT:
- HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
- OPTIONS:
- 获取服务器支持的HTTP请求方法;也是黑客经常使用的方法。
- 用来检查服务器的性能, 例如:AJAX进行跨域请求时的预检,需要向另外一个域名的资源发送一个HTTP OPTIONS请求头,用以判断实际发送的请求是否安全。
- 该请求方法的响应不能缓存。
- TRACE:
- 回显服务器收到的请求,主要用于测试或诊断。
- GET:
使用习惯
分页情况
# 不太好的例子,没有分页信息 Status:200 OK [ { "id":1, "url": "http://baoshu.red/mypost/1", }, { "id":2, "url": "http://baoshu.red/mypost/2", }, ] # 正确信息 Status:200 OK X-Togal-Count: 213 Link:<http://liuying.name/mypost?page=2>; rel="next", <http://liuying.name/mypost?page=2>; rel="last" [ { "id":1, "url": "http://liuying.name/mypost/1", }, { "id":2, "url": "http://liuying.name/mypost/2", }, ]
201 created 相应应该带有新资源Location
405 Method Not Allowed相应,应该带有Allow头
对输出结果不过渡包装
HTTP/1.1 200 OK { 'success':true, 'data':{ 'id':1, 'name':'liuying'), } # 替代例子 HTTP/1.1 200 OK { 'id':1, 'name':'liuying'),
版本控制
- 在URI中显示(提倡), http://api.liuying.com/api/v2
- 放在请求头(GitHub), Accept:application/vnd.github.v3+json
- 自定义请求头(不推荐), X-Api-Version:1
10.3. 序列化/反序列化¶
10.3.1. 名词解释¶
- 序列化就是指把程序对象转换为字节序列的过程, 是models->json->bytes过程
- 反序列化就是指把字节序列恢复为程序对象的过程, 是序列号的逆过程
- 序列化最重要的作用:
- 在传递和保存对象时.保证对象的完整性和可传递性
- 对象转换为有序字节流,以便在网络上传输或者保存在本地文件中
- 反序列化的最重要的作用:
- 根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。
- 核心作用就是对象状态的保存和重建。(整个过程核心点就是字节流中所保存的对象状态及描述信息)
10.3.2. json/xml的数据传递:¶
远程信息传输一般采用json/xml格式
- 在数据传输(也可称为网络传输)前,先通过序列化工具类将对象序列化为json/xml文件
- 在数据传输(也可称为网络传输)后,再将json/xml文件反序列化为对应语言的对象
10.3.3. 序列化优点:¶
- 将对象转为字节流可以存储到硬盘上,把序列化的对象,通过反序列化为原来的对象,并且序列化的二进制序列能够减少存储空间(永久性保存对象)。
- 序列化成字节流形式的对象可以进行网络传输(二进制形式),方便了网络传输。
- 通过序列化可以在进程间传递对象。
10.3.4. 序列化算法需要做的事:¶
- 将对象实例相关的类元数据输出
- 递归地输出类的超类描述直到不再有超类
- 类元数据输出完毕后,从最顶端的超类开始输出对象实例的实际数据值。
10.4. Django_Rest FrameWork¶
django restuframework为django项目提供restful支持,让django项目能快速提供API 支持。
如果为后台框架提供API支持,最核心的功能应该是快速的序列化和反序列化。
10.5. 教学案例¶
创建项目
v7_api
创建工程
tuling_rest
编写models文件中的类,包括Student, Room
# tuling_rest/models.py class Student(models.Model): name = models.CharField(max_length=20, default="NoName") age = models.IntegerField(default=18) score = models.IntegerField(default=60) class Room(models.Model): name = models.CharField(max_length=20) room_id = models.CharField(max_length=10, default="00000") stu_amount = models.IntegerField(default=0) location = models.CharField(max_length=50) desc = models.CharField(max_length=200)
设置
settings.py
INSTALLED_APPS = [ ... ... 'rest_framework', #Rest框架 'tuling_rest', ] #对DRF进行配置,不需要就不用1 REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', 'PAGE_SIZE': 2 }
添加文件
tuling_rest/serializers.py
#从drf库中导入序列化模块 from rest_framework import serializers from .models import Student, Room class StudentSerializer(serializers.ModelSerializer): ''' 序列化的时候,可以用单个model实例来初始化,也可以用queryset对象实例化,但需要设置many=True ''' class Meta: # 这个用来序列化Student模型 model = Student #只序列化模型中的两个属性:name,score fields = ("name", "score") ''' 实现create和update函数 ''' #如果是是创建类型的请求,则调用这个 def create(self, validated_data): return Student.objects.create(**validated_data) #如果是更新类型的请求 def update(self, instance, validated_data): instance.name = validated_data.get('name', instance.name) instance.age = validated_data.get('age', instance.age) instance.score = validated_data.get('score', instance.score) instance.save() return instance class RoomSerializer(serializers.ModelSerializer): class Meta: model = Room fields = ("room_id", "stu_amount")
编写视图函数
编写DRF的视图的时候,一般我们建议使用DRF自带的一些视图类,具体请参看代码修改路由
v1_api/urls.py
迁移数据库
编写测试test01,对基本Serializer进行测试
- 权限
- 建立permissions.py
- 添加权限IsMe
- 在视图中导入IsMe并使用