python之路60 drf从入门到成神 1 API restful规范 序列化反序列化概念 基于django原生编写5个接口 drf介绍和快速使用 cbv源码分析
老刘讲课资料获取
# 个人博客:https,证书过期,忽略
https://www.liuqingzheng.top/
# cnblogs博客(后期迁移到这里,高级部分的内容)
https://www.cnblogs.com/liuqingzheng
# 知乎
https://www.zhihu.com/people/justin_liu
drf整体内容
# 1 入门规范
web开发模式
api接口
接口测试工具
restful规范
序列化反序列化
drf快速使用
APIView,Request类
drf把django的好多东西都重写了
# 2 序列化组件(重要)
基本序列化类
模型类序列化类
如何序列化
如何反序列化
反序列化的数据校验功能
# 3 请求与响应
drf的request已经不是原来django的request了
drf的reponse已经不是原来django的reponse了
指定可以接收请求的编码方式
指定响应格式
# 4 视图组件(重点) View
两个视图基类
5个视图扩展类
9个视图子类
视图集
# 5 路由
自动生成路由
# 6 认证(登录认证),权限,频率 (重点)
# 7 过滤,排序,分页(次重点)
# 8 自动生成接口文档
----------------------------------------------
# 9 JWT 登录认证的,区别与cookie和session,主流
# 10 后台管理美化(django原生的很丑,simpleui二次开发)
# 11 基于角色的访问控制,权限的控制
web应用模式
# django web框架,专门用来写web项目
# 之前学的,写的bbs项目,图书管理系统,用的是 前后端混合开发
后端人员,写后端,也要写【模板语法】---》xx.html的python代码
全栈开发-->前后端混合时代,比较多
# 从今天开始,学的是前后端分离
后端人员,一点前端都不需要动,只需要写接口即可
全栈开发---》web后端,前端框架(vue,react)
前后端不分离
前后端分离
前后端结合
API接口
# 为了在团队内部形成共识、防止个人习惯差异引起的混乱,我们需要找到一种大家都觉得很好的接口实现规范,而且这种规范能够让后端写的接口,用途一目了然,减少双方之间的合作成本【前后端】
# 通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
http://127.0.0.1/books/
点赞,点踩 就是API接口
# api接口:就是前后端交互的媒介(web API接口的四大特点:)
1 url地址:https://api.map.baidu.com/place/v2/search
2 请求方式:get,post,delete,put,patch,
3 请求参数:json或xml格式的key-value类型数据
早些年 前后端交互使用xml格式----》ajax:异步JavaScript和XML
后来,随着json格式的出现,成了主流,直到现在
以后:一定会出现,比json更高效的交互格式,更安全
4 响应结果:json或xml格式的数据
# api接口案例(两种序列化方式json和xml)
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=xml
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=上海&query=肯德基&output=xml
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=%E4%B8%8A%E6%B5%B7&query=%E8%82%AF%E5%BE%B7%E5%9F%BA&output=json
https://api.map.baidu.com/place/v2/search?ak=6E823f587c95f0148c19993539b99295®ion=上海&query=肯德基&output=json
接口测试工具postman
# 作为后端,写好了接口,我们自己要测试通过,再给别人用
# 写的接口,需要有个工具测试
浏览器只能发送get请求,不能自动发送post,delete请求
postman---》开源软件,只是谷歌浏览器的插件,越做好好,后来可以安装到操作系统上,再后来,收费
postwoman
很多很多其他的,不同公司用的也可能不一样,你只需要明白一个点,这个工具只是用来发送http请求
# postman的使用
1 官方下载:https://www.postman.com/downloads/?utm_source=postman-home----》Postman-win64-Setup.exe
2 安装,双击即可
restful规范*****
# 概念
REST全称是Representational State Transfer,中文意思是表述:表征性状态转移,它首次出现在2000年Roy Fielding的博士论文中。
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中
# 10个规范
1.数据的安全保障,通常使用https(http+SSL/tls)协议
url链接一般都采用https协议进行传输
采用https协议,可以提高数据交互过程中的安全性
2.接口中带api标识
https://api.lqz.com/books
https://www.lqz.com/api/books 我们用这个
3.多版本共存,路径中带版本信息
https://api.lqz.com/v1/login
https://www.lqz.com/api/v2/login
4.数据即是资源,均使用名词,尽量不出现动词(最核心的)
接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
接口形式如下
https://api.baidu.com/users
https://api.baidu.com/books
特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义、
https://api.baidu.com/login
5.资源操作由请求方式决定(method)
操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查的动作
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.在请求地址中带过滤条件
https://api.baidu.com/books?name=红&price=99
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响应状态码:1xx:请求正在处理,2xx:成功响应,3xx:重定向,4xx:客户端错误,5xx:服务端错误
这个网址详细讲解 https://blog.csdn.net/li_chunlong/article/details/120787872
公司内部规定的响应状态码,放在响应体中
{code:0} 咱们后期一般使用100 101 102这种
8.返回数据中带错误信息
{
code:0
msg:"ok/用户名错误"
}
9.返回的结果应该符合以下规范 好多公司不遵循这个
GET 获取所有数据:返回资源对象的列表(数组)[{name:红楼梦,price:99},{name:红楼梦,price:99},{name:红楼梦,price:99},]
GET 单个对象:返回单个资源对象:{name:红楼梦,price:99}
POST 新增对象:返回新生成的资源对象:{name:西游记,price:99}
PUT 修改对象:返回完整的资源对象:{name:西游记,price:100}
DELETE删除:返回一个空文档
10.响应数据中带链接
{
"status": 0,
"msg": "ok",
"results":[
{
"name":"肯德基(罗餐厅)",
"img": "https://image.baidu.com/kfc/001.png"
}
}
序列化与反序列化
# api接口开发,最核心最常见的一个过程就是序列化,所谓序列化就是把【数据转换格式】,也就是序列化分为两个阶段:
#序列化:把我们识别的数据转换成指定的格式提供给别人
字典,列表 json格式存到文件中了
例如:我们在django中获取到的数据默认是模型对象,但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人
read
#反序列化:把别人提供的数据转换/还原成我们需要的格式。
例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中。
write
基于django原生编写5个接口
以后写的接口,基本上都是5个接口及其变形
查询所有
查询单个
新增一个
修改一个
删除一个
基于books单表为例,写5个接口
先创建book表
from django.db import models
class Book(models.Model):
name = models.CharField(max_length=32)
price = models.CharField(max_length=32)
publish = models.CharField(max_length=32)
表迁移
python manage.py makemigrations
python manage.py migrate
录入假数据:直接录,后台管理录
写查询所有接口 遵循restful规范,使用cbv
查询所有
http://127.0.0.1:8000/api/v1/books/ get请求:获取所有书
新增一个
http://127.0.0.1:8000/api/v1/books/ post请求:新增一本书
查询单个
http://127.0.0.1:8000/api/v1/books/3 get请求:获取主键为3的书
需要新增路由
path('api/v1/books/<int:pk>', views.BooksDetailView.as_view()),
# re_path('api/v1/books/(?P<pk>\d+)', views.BooksDetailView.as_view()),
修改一个 put提交的数据,不能从requets.POST中取
https://api.baidu.com/books/3 put请求:修改主键为3的书
删除一个
https://api.baidu.com/books/4 delete请求:删除主键为4的书
drf介绍和快速使用
# djangorestframework: drf帮助我们快速的实现符合restful规范的接口
# django最新4.x,一般都会用最新版的上一版3.x
# drf最新支持到django3.x , 最新不支持2.x
# 安装drf
pip3.8 install djangorestframework -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
# 由于是django2.x 它发现它不支持,它会自动卸载django,安装最新的django 4.x
直接执行
pip3.8 install django==2.2.2 -i http://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com
虽然drf不支持django2.x 但是安装上之后还是可以使用
# 使用drf编写5个接口
# views中
from .serializer import BookSerializer
from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
# serializer
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
# urls中
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
path('admin/', admin.site.urls),
]
# 两个列表相加 [1,2,4] + [6,7,8]= [1,2,4,6,7,8]
urlpatterns += router.urls
总结 在用drf进行5个接口的编写中 路由是拼接构成的并且不用区分urlencoded或form-data或json编码方式 三种都可以用
GET与POST请求中是用路由直接访问
eg:
http://127.0.0.1:8000/books/
PUT与DELETE请求是用路由加上id加斜杠(一定要加斜杠)
eg:
http://127.0.0.1:8000/books/3/
避坑点
如果用浏览器访问drf编写的5个接口(一般用postman测试)
需要在注册app的地方加上 'rest_framework',
程序报错
浏览器报错
cbv源码分析
# 1 路由中写的:path('api/v1/books/', views.BookView.as_view()),第二个参数无论是fbv还是cbv放的都是函数内存地址
当请求来了,匹配成功会执行,views.BookView.as_view()(request)
views.BookView.as_view()执行结果是View的类方法as_view返回的结果是内层函数view,是个函数内层地址
[as_view中的内存函数,闭包函数]---》
本身请求来了,匹配成功,会执行view(request)
def view(request, *args, **kwargs):
return self.dispatch(request, *args, **kwargs)
self.dispatch View类的方法
http_method_names = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'] # View类的数据 下面dispatch反射方法用来确定到底是什么请求方式 不存在的请求方式无法继续执行
def dispatch(self, request, *args, **kwargs):
# request.method请求方式转成小写,必须在列表中才能往下走
if request.method.lower() in self.http_method_names:
# 这一步如何确定是什么类型的请求 根据http_method_not_allowed
# 反射,去self【视图类的对象:BookView】,去通过get字符串,反射出属性或方法
# handler就是BookView类的get方法
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 执行 BookView的get(request)---->get请求就会执行BookView的get方法,post请求就会执行BookView的post方法
return handler(request, *args, **kwargs)