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格式数据返回,其他不支持
  • 列表页视图没有分页,排序,过滤功能
posted @ 2019-10-17 15:45  sinder2018  阅读(54)  评论(0)    收藏  举报