Django-RestFramework(五)
一、REST API
- RESTful是一种开发理念
- 是设计风格而不是标准
- 是REpresentational State Transfer的缩写
- 具象状态传输
- 每一个URL代表一种资源
- json格式数据
- text文本
- 图片、视频等
- 客户端和服务器之间,传递这种资源的某种表现形式
- 通过请求头中Content-Type来致命传给服务端的参数类型
"text/plain","application/xml","text/html","application/json","image/gif","image/jpeg",
"application/x-www-form-urlevcoded"
-
- 通过请求头中Accept来指明希望接受服务端的数据类型
Accept: application/json,application/xml;q=0,*/*;q=0.8
- 客户端通过HTTP动词,指明对服务器端资源要进行的操作

二、REST常用的设计规则
1、URL
命名
- 尽量使用名词复数形式
- 往往与数据库的表名对应
#差的设计
/getProjects
/listUsers
过滤条件
- 如果记录数量很多,服务器不可能将所有数据返回前端
?limit=10 :指定返回记录的数量
?offset=10 :指定返回记录的开始位置
?page=2&size=10 :指定第几页和每页的数据条数
?sort=name :指定返回结果按照哪个字段排序,以及排序顺序
域名
- 尽量使用专用域名
http://api.keyou.site
版本
-
在URL中呈现版本号
http://api.keyou.site/app/0.1/
http://api.keyou.site/app/0.2/
- 在请求头中出现版本号
Accept: application/vnd.example+json;version=1.1
2、 HTTP请求动词
含义
#常见的HTTP动词有下面四个(括号里是对应的SQL命令)
GET(SELECT) :从服务器获取资源(一项或者多项)
POST(CREATE) :在服务器新建一个资源
PUT(UPDATE) :在服务器上更新资源(客户端提供改变后的完整资源)
DELETE(DELETE) :从服务器删除资源
还有三个不常用的HTTP动词
PATCH(UPDATE WHERE) :在服务器部分更新(更新)资源(客户端提供改变的属性)
HEAD :获取资源的元数据
OPTIONS :获取关于资源的哪些属性是客户端可以改变的信息
例子
GET /project #获取所有项目信息
POST /projects #创建一个新项目
GET /projects/6 #获取ID为6的项目信息
PUT /projects/6 #更新ID6的项目信息(全更新)
PATCH /projects/6 #更新ID为6的项目信息(部分更新)
DELETE /projects/6 #更新ID为6的项目
GET /projects/6/interfaces #获取ID为6的项目信息中所有的接口信息
3、状态码
status codes
200 OK -[GET] 服务器成功返回用户请求的数据
201 CREATE - [POST/PUT/PATCH]:用户新建或修改数据成功
204 NO CONTENT - [DELETE]:用户删除数据成功
400 INVAILIDV REQUEST - [POST/PUT/PATCH]:用户请求有误(请求参数有误)
401 Forbidden - [*] :表示用户没有权限(令牌、用户名、密码错误)
405 NOT FOUND - [*]:用户请求的路径不存在
500 INTERNAL SERVER ERROR - [*]:服务器发生错误
4、返回结果
- 服务器向用户返回的结果应该符合以下规范
GET /projects #返回所有项目的列表(json数组)
GET /projects/6 #返回单个项目信息(单个json)
POST /projects/6 #返回新生成的项目信息(单个json)
PUT /projects/6 #返回更新之后,完整的项目信息(单个json)
PATCH /projects/6 #返回更新之后,完整的项目信息(单个json)
DELETE /projects/6 #返回空
5、错误处理
- 当请求有误时,服务器需将错误的信息以json格式数据的形式返回
{
"detail":"身份认证信息未提供。”,
"status_code": 401
}
三、基础阶段综合演练
projects/views.py
1、创建对项目数据进行CRUD操作的接口
from django.http import HttpResponse, JsonResponse from django.views import View from projects.models import Projects import json # from rest_framework.viewsets import ModelViewSet # from projects.serializer import ProjectsSerializer class ProjectsList(View): def get(self, request): #1、从数据库中获取所有的项目数据 projects_all = Projects.objects.all() #2、将数据库模型实例转化为字典类型(嵌套字典的列表) projects_list = [] for project in projects_all: projects_list.append({ 'name': project.name, 'leader': project.leader, 'tester': project.tester, 'programer': project.programer, 'pubish_app': project.pubish_app, 'desc': project.desc }) return JsonResponse(projects_list, safe=False) def post(self, request): """新增项目""" #1、从前端获取json格式数据,转化为python中的类型 #2、为了严谨性,需要做各种校验数据 json_data = request.body.decode('utf-8') python_data = json.loads(json_data, encoding='utf-8') #3、向数据库新增项目 # Projects.objects.create(name=python_data['name'], # leader=python_data['leader'], # tester=python_data['tester'], # programer=python_data['programer'], # pubish_app=python_data['pubish_app'], # desc=python_data['desc']) project = Projects.objects.create(**python_data) #4、将模型类转换为字典,然后返回 one_dict = { 'name': project.name, 'leader': project.leader, 'tester': project.tester, 'programer': project.programer, 'pubish_app': project.pubish_app, 'desc': project.desc } return JsonResponse(one_dict,status=201) class ProjectsDetail(View): def get(self, request, pk): #1、校验前端传递的pk(项目ID),类型是否正确(正整数),在数据库中是否存在 #省略 #2、获取指定pk值得项目 project = Projects.objects.get(id=pk) #3、将模型类对象转换为字典 one_dict = { 'name': project.name, 'leader': project.leader, 'tester': project.tester, 'programer': project.programer, 'pubish_app': project.pubish_app, 'desc': project.desc } return JsonResponse(one_dict) def put(self, request, pk): #1、校验前端传递的pk(项目ID),类型是否正确(正整数),在数据库中是否存在 #省略 #2、获取指定pk值得项目 project = Projects.objects.get(id=pk) #3、从前端获取json格式数据,转化为python中的类型 json_data = request.body.decode('utf-8') python_data = json.loads(json_data, encoding='utf-8') #4、更新项目 project.name = python_data['name'] project.leader = python_data['leader'] project.tester = python_data['tester'] project.programer = python_data['programer'] project.pubish_app = python_data['pubish_app'] project.desc = python_data['desc'] project.save() #5、将模型类对象转换成python中的类型 one_dict = { 'name': project.name, 'leader': project.leader, 'tester': project.tester, 'programer': project.programer, 'pubish_app': project.pubish_app, 'desc': project.desc } return JsonResponse(one_dict, status=201) def delete(self, request, pk): #1、校验前端传递的pk(项目ID),类型是否正确(正整数),在数据库中是否存在 project = Projects.objects.get(id=pk) project.delete() return JsonResponse(None, safe=False, status=204)
2、创建接口的任务
- 校验用户数据
- 将请求的数据(如json格式)转换成模型对象
- 反序列化
- 将其他格式(json,xml等)转换为程序中的数据类型
- 将json格式的字符串转换为Django中的模型类对象
- 反序列化
- 操作数据库
- 将模型类对象转换为响应的数据(如json格式)
- 序列化
- 将程序中的数据类型转换为其他格式(json、xml)
- 例如将Django中的模型对象转换为json字符串
- 序列化
3、数据增删改查流程
增
-
校验请求参数 ->反序列化 -> 保存数据 -> 将保存的对象序列化并返回
删
-
判断要删除的数据是否存在 -> 执行数据库删除
改
- 判断要修改的数据是否存在 -> 校验请求参数 -> 反序列化 ->保存数据 ->将保存的对象序列化并返回
查
- 查询数据库 ->将数据序列化并返回
4、上述操作有哪些痛点
- 代码冗余极其严重,不符合优秀测开风格
- 数据校验麻烦,可复用性差
- 编码没有统一规范,杂乱无章
- 写的代码非常多,不够简洁
- 只支持json格式传参,不支持form表单传参
- 仅能支持json格式数据返回,其他不支持
- 列表页视图没有分页,排序,过滤功能

浙公网安备 33010602011771号