Django REST framework基础篇

drf_logo

在使用Django REST framework之前需要了解一些知识

简述

1.Web应用模式

在开发Web应用中,有两种应用模式:

  1. 前后端不分离[客户端看到的内容和所有界面效果都是由服务端提供出来的。]

前后端不分离

  1. 前后端分离【把前端的界面效果(html,css,js分离到另一个服务端,python服务端只需要返回数据即可)】

    前端形成一个独立的网站,服务端构成一个独立的网站

前后端分离

2. api接口

为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本。

目前市面上大部分公司开发人员使用的接口服务架构主要有:restful、rpc。

rpc: 翻译成中文:远程过程调用[远程服务调用].

服务端提供一个同一个地址:http://api.zhan.cn/

post请求

action=get_all_student&params=301&sex=1

接口多了,对应函数名和参数就多了,前端在请求api接口时,就会比较难找.容易出现重复的接口

restful: 翻译成中文: 资源状态转换.

把后端所有的数据/文件都看成资源,那么接口请求数据,本质上来说就是对资源的操作了.

web项目中操作资源,无非就是增删查改.所以要求在地址栏中声明要操作的资源是什么,然后通过http请求动词来说明对资源进行哪一种操作.

POST http://www.zhan.cn/api/students/ 添加学生数据

GET http://www.zhan.cn/api/students/ 获取所有学生

DELETE http://www.zhan.cn/api/students// 删除id=pk的一个学生

PUT http://www.zhan.cn/api/students// 修改一个学生的全部信息 [id,name,sex,age,]

PATCH http://www.zhan.cn/api/students// 修改一个学生的部分信息[age]

3. RESTful API规范

restful

REST全称是Representational State Transfer,首次出现在2000年一个博士论文中。

RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中。

这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源。

而对于数据资源分别使用POST、DELETE、GET、UPDATE等请求动作来表达对数据的增删查改。

请求方法 请求地址 后端操作
GET /students 获取所有学生
POST /students 增加学生
GET /students/ 获取主键为pk的学生
PUT /students/ 修改主键为pk的学生
DELETE /students/ 删除主键为pk的学生

事实上,我们可以使用任何一个框架都可以实现符合restful规范的API接口。

参考文档:http://www.runoob.com/w3cnote/restful-architecture.html

接口实施过程中,会存在幂等性。所谓幂等性是指代客户端发起多次请求是否对于服务端里面的资源产生不同结果。如果多次请求,服务端结果还是一样,则属于幂等接口,如果多次请求,服务端产生结果是不一样的,则属于非幂等接口。在http请求,get/put/patch/delete都属于幂等性接口,post属于非幂等接口。

4. 序列化

api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把数据转换格式,序列化可以分两个阶段:

序列化: 把我们识别的数据转换成指定的格式提供给别人。

例如:我们在django中获取到的数据默认是模型对象,但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。

反序列化:把别人提供的数据转换/还原成我们需要的格式。

例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中。

Django Rest Framework

1.简介

核心思想: 缩减编写api接口的代码

用来帮助开发者快速构建 RESTful Web API 的强大而又灵活的工具

drf_logo

官方文档:http://www.django-rest-framework.org/

特点

  • 提供了定义序列化器 Serializer 的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化;
  • 提供了丰富的类视图、Mixin 扩展类,简化视图的编写;
  • 丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要;
  • 多种身份认证和权限认证方式的支持;
  • 内置了限流系统以及过滤、分页
  • 直观的 API web 界面;
  • 可扩展性,插件丰富

Django REST framework 是在 Django 框架的基础上进行扩充,从而可以帮助我们简化部分的代码编写,大大提高 RESTful Web API 的开发速度。

  1. 在序列化与反序列化时,虽然操作的数据不尽相同,但是执行的过程却是相似的,也就是说这部分代码是可以复用简化编写的。
  2. 在开发 REST API 的视图中,虽然每个视图具体操作的数据不同,但增、删、改、查的实现流程基本套路化,所以这部分代码也是可以复用简化编写的:
    • :校验请求数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
    • :判断要删除的数据是否存在 -> 执行数据库删除
    • :判断要修改的数据是否存在 -> 校验请求的数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
    • :查询数据库 -> 将数据序列化并返回

2.使用

1.安装Django REST framework

安装 Django REST framework 需要以下依赖:

  • Python (3.5, 3.6, 3.7, 3.8)
  • Django (1.11, 2.0, 2.1, 2.2, 3.0)

pip install djangorestframework

2.注册rest_framework应用

settings.pyINSTALLED_APPS中添加’rest_framework’。

1
2
3
4
INSTALLED_APPS = [
...
'rest_framework',
]

3.在应用中models.py创建模型类

1
2
3
4
5
6
7
8
9
10
11
12
class Student(models.Model):
# 模型字段
name = models.CharField(max_length=100,verbose_name="姓名")
sex = models.BooleanField(default=1,verbose_name="性别")
age = models.IntegerField(verbose_name="年龄")
class_null = models.CharField(max_length=5,verbose_name="班级编号")
description = models.TextField(max_length=1000,verbose_name="个性签名")

class Meta:
db_table="tb_student"
verbose_name = "学生"
verbose_name_plural = verbose_name

4.创建序列化器

通常,API 包含两个方向的操作,其一是客户端向服务器请求数据,其二是客户端向服务器提交数据。当客户端向服务器请求数据时,服务器在数据库检索相应数据,经过序列化器序列化,再由视图交给客户端;客户端向服务器提交数据时,数据经由视图层进行处理,而后序列化器反序列化,最后存入数据库。

图片描述

在 Restful Web API 中,序列化器相当于客户端和数据库之间数据对接的桥梁,它可将服务器中的数据,序列化为客户端可解析的数据形式,相反,也可将客户端提供的数据,反序列化为符合数据库要求的数据形式。

在应用中新建 serializers.py 用于保存该应用的序列化器。

创建一个 StudentsSerializer 用于序列化与反序列化学生信息:

1
2
3
4
5
6
7
8
9
10
11
# serializers.py
from rest_framework import serializers
from AppDemo.models import StudentsModel

class StudentsSerializer(serializers.ModelSerializer):

class Meta:
# 对StudentsModel进行序列化
model = StudentsModel
# __all__表示对 StudentsModel 中所有字段序列化进行序列化
fields = '__all__'
  • model :指明该序列化器处理的数据字段从模型类 StudentsModel 参考生成;
  • fields :指明该序列化器包含模型类中的哪些字段,’all’指明包含所有字段。

5.编写视图

在 Restful Web API 中,视图扮演的角色是数据处理器,在应用的 views.py 中创建视图 BookInfoViewSet,这是一个视图集合。

1
2
3
4
5
6
7
8
9
10
# views.py
from rest_framework import viewsets
from AppDemo.models import StudentsModel
from AppDemo.serializers import StudentsSerializer

class StudentsViewSet(viewsets.ModelViewSet):

queryset = StudentsModel.objects.all()
# 使用上一步创建的StudentsSerializer对模型进行序列化
serializer_class = StudentsSerializer
  • queryset 指明该视图集在查询数据时使用的查询集
  • serializer_class 指明该视图在进行序列化或反序列化时使用的序列化器。

6.定义路由

路由是用来定义 RESTful Web API 不同接口所对应的不同路径地址,在应用的 urls.py 中定义路由信息。

在students应用的urls.py中定义路由信息。

1
2
3
4
5
6
7
8
9
10
from . import views
from rest_framework.routers import DefaultRouter

# 路由列表
urlpatterns = []

router = DefaultRouter() # 可以处理视图的路由器
router.register('students', views.StudentViewSet) # 向路由器中注册视图集

urlpatterns += router.urls # 将路由器中的所以路由信息追到到django的路由列表中

最后把students子应用中的路由文件加载到总路由文件中.

1
2
3
4
5
6
7
from django.contrib import admin
from django.urls import path,include

urlpatterns = [
path('admin/', admin.site.urls),
path("api/",include("students.urls")),
]

7.运行测试

终端中运行当前程序(与运行 Django 一样):

1
python manage.py runserver

此时,我们的 RESTful Web API 已构建完毕。由于我们是在本地测试,所以 API 域名部分采用本机地址。在浏览器地址栏输入 http://127.0.0.1:8000/api,即可看到当前项目中所有接口连接。

图片描述

点击链接 http://127.0.0.1:8000/api/students/ 即可前往学生信息接口,可以获取所有学生的信息,如下图所示:

图片描述

在页面底部的表单中,我们可以输入学生信息,点击 POST 按钮,即可实现向学生列表中添加新的学生信息:

图片描述

点击 POST 按钮后,返回如下信息:

图片描述

此时再点击 GET 按钮,我们发现上一步中添加的学生(小白)已经显示在所有学生信息中。

图片描述

在浏览器中输入网址 127.0.0.1:8000/api/students/2/,可以访问获取单个学生信息的接口(id 为 2 的学生),如下图所示:

图片描述

如果需要修改该学生的信息,可在页面底部表单中填写需要修改的信息,即可访问修改单个学生的接口。我们将小红年龄修改为 20:

图片描述

点击 PUT,返回如下页面信息,此时小红的年龄信息已经修改完毕:

图片描述

点击 DELETE 按钮,可以访问删除学生的接口

图片描述

点 DELETE 后返回,如下页面,此时 id 为 2 的学生小红已被删除:

5e9592a709fa7aca25920374

都看到这里了,不赏点银子吗^v^