DRF 整体回顾
DRF 是什么?
Django REST framework is a powerful and flexible toolkit for building Web APIs.
上面是官网的介绍,我稍微修改一下可能更清楚:
Django REST framework is a powerful and flexible toolkit works with Django for building Restful Web APIs.
翻译过来:DRF是一个强大灵活的Django工具包,用于在Web后台构建Restful接口
在Django下构建Restful接口的工具不止一个(比如Tastypie),但是当下最出名的就是DRF,版本更新速度快、社区活跃度好,文档比较完善。
为什么要有接口
因为我们做开发的会有两种开发模式。
第一种是:前后端混合开发
。也就是所谓的不分离。第二种就是:前后端分离式开发
,我们后端只写API接口。
写到这里,可能会有人问 什么是API接口?
API接口:
API(应用程序接口)是一种软件中介,它允许两个不相关的应用程序相互通信。 它就像一座桥梁,从一个程序接收请求或消息,然后将其传递给另一个程序,翻译消息并根据API 的程序设计执行协议。 API 几乎存在于我们数字生活的各个方面,可以说是我们现代插件、数字接口和软件通信环境的隐藏支柱。
写了接口,都会带什么呢?都会给谁用呢?我们所写的接口,是一个前后端交互的媒介,它会携带
diff
-请求地址
-请求方式
-请求参数:地址,请求体
-返回数据
都谁会用到接口?---> WEB端,APP端,第三方调用
接口规范 --- restful 规范
1. 数据的安全保障,通常使用https协议进行传输
2. url地址中带接口标识:一般这样:
-https://api.baidu.com
-https://www.baidu.com/api
3. 多版本共存,url地址中带版本信息
-https://api.baidu.com/v1/login/
-https://api.baidu.com/v2/login/
4. 数据即是资源,均使用名词:
url地址尽量使用名词
接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
https://api.baidu.com/users
https://api.baidu.com/books
https://api.baidu.com/book
注:一般提倡用资源的复数形式,在url链接中不要出现操作资源的动词,错误示范:https://api.baidu.com/delete-user
特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
https://api.baidu.com/place/search
https://api.baidu.com/login
5. 资源操作由请求方式决定
#操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
https://api.baidu.com/books
- get请求:获取所有书
https://api.baidu.com/books/1
- get请求:获取主键为1的书
https://api.baidu.com/books
- post请求:新增一本书书
https://api.baidu.com/books/1
- put请求:整体修改主键为1的书
https://api.baidu.com/books/1
- delete请求:删除主键为1的书
6. url地址中带过滤条件 ?
后带过滤条件
bash
`https://api.baidu.com/books` -get请求表示查询所有图书,要查名字中有红的图书
`https://api.baidu.com/books?name_contains=红 `
`https://api.example.com/v1/zoos?limit=10`:指定返回记录的数量
`https://api.example.com/v1/zoos?offset=10`:指定返回记录的开始位置
`https://api.example.com/v1/zoos?page=2&per_page=100`:指定第几页,以及每页的记录数
`https://api.example.com/v1/zoos?sortby=name&order=asc` :指定返回结果按照哪个属性排序,以及排序顺序
`https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件`
7. 响应状态码(http响应中带状态码)
-http的响应状态码:https://blog.csdn.net/meng2lin/article/details/128955775
-1xx
:请求正在处理
-2xx
:请求成功 200 201
-3xx
:重定向
-4xx
:客户端错误
-5xx
:服务的错误
-http的响应的数据中带状态码(公司自己规定的)
-{code:100}
8. 返回的数据中带错误信息:
{code:101,msg:用户名或密码错误}
{code:100,msg:成功}
9. 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
GET /books:返回资源对象的列表(数组)
python
-[{name:武松打虎,price:88},{name:西游记,price:88}]
-{code:100,msg:成功,data:[{name:武松打虎,price:88},{name:西游记,price:88}]}
GET /books/1:返回单个资源对象
python
-{name:武松打虎,price:88} ---{code:100,msg:成功,data:{name:武松打虎,price:88}}
POST /books:返回新生成的资源对象
python
-{id:4,name:武松打虎,price:88} ---{code:100,msg:成功}
PUT /books/4:返回完整的资源对象
python
-{id:4,name:武松打虎,price:188} ---{code:100,msg:修改成功}
DELETE /books/4:
python
返回一个空文档 ---{code:100,msg:删除成功}
10. 返回的结果中带url链接
接口测试工具
目前比较常用的有POSTMAN
简单来说,POSTMAN就是一个可以直接发送HTTP请求的工具
GET请求 和 POST请求 的区别
GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二。
最直观的区别就是 GET
把参数包含在URL中, POST
通过 request body
传递参数。
另外,你可能列出了
- GET在浏览器回退时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被Bookmark,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST么有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
- GET参数通过URL传递,POST放在Request body中
但实际上,GET和POST本质上是没有区别的。只是两种不同的HTTP请求方式
HTTP 和 HTTPS 的区别
基本概念
HTTP(HyperText Transfer Protocol:超文本传输协议)是一种用于分布式、协作式和超媒体信息系统的应用层协议。 简单来说就是一种发布和接收 HTML 页面的方法,被用于在 Web 浏览器和网站服务器之间传递信息。
HTTP 默认工作在 TCP 协议 80 端口,用户访问网站 http:// 打头的都是标准 HTTP 服务。
HTTP 协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此,HTTP协议不适合传输一些敏感信息,比如:信用卡号、密码等支付信息。
HTTPS(Hypertext Transfer Protocol Secure:超文本传输安全协议)是一种透过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。
HTTPS 默认工作在 TCP 协议443端口,它的工作流程一般如以下方式:
- 1、TCP 三次同步握手
- 2、客户端验证服务器数字证书
- 3、DH 算法协商对称加密算法的密钥、hash 算法的密钥
- 4、SSL 安全加密隧道协商完成
- 5、网页以加密的方式传输,用协商的对称加密算法和密钥加密,保证数据机密性;用协商的hash算法进行数据完整性保护,保证数据不被篡改。
HTTP 和 HTTPS 的区别
- HTTP 明文传输,数据都是未加密的,安全性较差,HTTPS(SSL+HTTP) 数据传输过程是加密的,安全性较好。
- 使用 HTTPS 协议需要到 CA(Certificate Authority,数字证书认证机构) 申请证书,一般免费证书较少,因而需要一定费用。证书颁发机构如:Symantec、Comodo、GoDaddy 和 GlobalSign 等。
- HTTP 页面响应速度比 HTTPS 快,主要是因为 HTTP 使用 TCP 三次握手建立连接,客户端和服务器需要交换 3 个包,而 HTTPS除了 TCP 的三个包,还要加上 ssl 握手需要的 9 个包,所以一共是 12 个包。
- http 和 https 使用的是完全不同的连接方式,用的端口也不一样,前者是 80,后者是 443。
- HTTPS 其实就是建构在 SSL/TLS 之上的 HTTP 协议,所以,要比较 HTTPS 比 HTTP 要更耗费服务器资源。
DRF 序列化 和 反序列化
api接口开发,最核心最常见的一个过程就是序列化
序列化: 把我们识别的数据转换成指定的格式提供给别人。
例如:我们在django中获取到的数据默认是模型对象(queryset),但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。
序列化:把别人提供的数据转换/还原成我们需要的格式。
例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中
序列化:drf称为 read
序列化
反序列化:drf称为 write
反序列化
请求和响应
请求:
diff
-请求源码:request对象
-request.data
-request.query_params
-跟之前一样
-request._request
-__getattr__
-请求能解析编码格式:parser_classes
-局部使用
-全局使用
响应
diff
-响应Response 源码
-data:响应体的内容,序列化后的数据给了他
-headers:响应头 django原生响应头 响应对象['xx']=xxx
-status:响应状态码
-响应编码格式--》浏览器,postman,看到的样子
-局部和全局配置
DRF 常用的几个层和组件
序列化类
from rest_framework import serializers
serializers.Serializer
or serializers.ModelSerializer
Serializer 和 ModelSerializer 的区别:
代码展示:
python
# 登录专用序列化
class LoginSerializer(serializers.ModelSerializer):
username = serializers.CharField()
password = serializers.CharField()
class Meta:
model = Staff
fields = ['username', 'password']
视图
最常用的也是最基础最底层的五大常用方法:增、删、改、查单、查所有
视图方法和他们之间的乱伦关系
来一个简单一点的版本
举例:
PYTHON
class LoginView(GenericViewSet):
# queryset = Staff.objects.all()
serializer_class = LoginSerializer
# 员工登录
@action(methods=['POST'], detail=False)
def login(self, request, *args, **kwargs):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
token = ser.context.get('token')
username = ser.context.get('username')
return Response({'code': 200, 'msg': '登录成功', 'token': token, 'username': username})
else:
return Response({'code': 1040, 'msg': ser.errors})
乱伦关系梳理
- 两个视图基类
APIVIew
-类属性
ini
renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
parser_classes = api_settings.DEFAULT_PARSER_CLASSES
authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
GenericAPIView:要使用序列化类,数据库打交道,就可以继承它
ini
-queryset = None
-serializer_class = None
-lookup_field = 'pk'
-filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
-pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
-get_queryset(self) #获取所有要序列化的数据,在里面拿到qs对象后要 .all()
-get_object # 获取单个对象
-get_serializer()--->内部调用了get_serializer_class--》最终返回序列化类的对象,传入要传的参数---》instance ,data many
-filter_queryset---》给ListModelMixin用了--》把配置的filter_backends 依次执行完成过滤
5个视图扩展类 =不是视图类,需要搭配GenericAPIView
ListModelMixin
,
CreateModelMixin
,
UpdateModelMixin
,
DestroyModelMixin
,
RetrieveModelMixin
一个视图类中写四个接口 --->
必须借助于ViewSetMixin
python
class BookView(ViewSetMixin,GenericAPIView,ListModelMixin,CreateModelMixin,RetrieveModelMixin,DestroyModelMixin):
queryset = None
serializer_class = None
路由
只要用了ViewSetMixin以及其子类,路由的写法就变了
我们需要导入 SimpleRouter
来生成新的路由
from rest_framework.routers import SimpleRouter
然后实例化得到一个对象并生成
router = SimpleRouter()
router.register('staff', StaffView, 'staff')
在urlpatterns
里面添加新路由的两种方法:
第一种方法:
from django.urls import path, include
ini
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(router.urls)),
]
第二种方法:
直接在 urlpatterns
的下面写urlpatterns += router.urls
认证组件
(待编辑)
频率组件
(待编辑)
权限组件
(待编辑)
JWT模块
(待编辑)