drf——restful规范、序列化反序列化、drf介绍和快速使用、drf之APIView源码
2023/5/17 1:22:04
本文主要是介绍drf——restful规范、序列化反序列化、drf介绍和快速使用、drf之APIView源码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.restful规范
# restful是一种定义API接口的设计风格,API接口的编写规范,尤其适用于前后端分离的应用模式中 这种风格的理念人为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源 我们可以使用任何一个框架都可以实现符合restful规范的API接口 # 10条规范 1.数据的安全保障,通常使用https协议进行传输 2.url地址中带接口标识:一般这样 -https://api.baidu.com -https://www.baidu.com/api 3.多版本共存,url地址中带版本信息(v1 v2版本信息) 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地址中带过滤条件 ?后带过滤条件 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:返回资源对象的列表(数组) -[{name:水浒传,price:88},{name:西游记,price:88}] -{code:100,msg:成功,data:[{name:水浒传,price:88},{name:西游记,price:88}]} GET /books/1:返回单个资源对象 -{name:水浒传,price:88} ---{code:100,msg:成功,data:{name:水浒传,price:88}} POST /books:返回新生成的资源对象 -{id:4,name:水浒传,price:88} ---{code:100,msg:成功} PUT /books/4:返回完整的资源对象 -{id:4,name:水浒传,price:188} ---{code:100,msg:修改成功} DELETE /books/4: 返回一个空文档 ---{code:100,msg:删除成功} 10.返回的结果中带url链接
2.序列化和反序列化
# api接口开发,最核心最常见的一个过程就是序列化 # 序列化: 把我们识别的数据转换成指定的格式提供给别人。 例如:我们在django中获取到的数据默认是模型对象(queryset),但是模型对象数据无法直接提供给前端或别的平台使用,所以我们需要把数据进行序列化,变成字符串或者json数据,提供给别人。 # 反序列化:把别人提供的数据转换/还原成我们需要的格式。 例如:前端js提供过来的json数据,对于python而言就是字符串,我们需要进行反序列化换成模型类对象,这样我们才能把数据保存到数据库中 # 序列化:drf称为 read 序列化 # 反序列化:drf称为 write 反序列化
3.drf介绍和快速使用
3.1 drf介绍
# Django中有个app djangorestframework(简称drf),帮助我们快速实现符合resful规范的接口 # pip下载:(有个坑) pip install djangorestframework==版本号 # 如果你是django2, 直接这样装,装最新drf,他们不匹配---》pip会自动把django卸载,安装最新django,安装最新drf # django3,这样没有任何问题 pip install djangorestframework --upgrade # 补充: -如果写了一个包,或app,想给别人用---》把你写的包,放到pypi上别人pip install 安装---》使用
3.2 drf快速使用
在应用下创建一个py文件 序列化类(serializer.py) from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__' 路由urls from app01.views import BookView from rest_framework.routers import SimpleRouter router = SimpleRouter() router.register('books',BookView,'books') urlpatterns = [ ] urlpatterns += router.urls 试图 from .serializer import BookSerializer from rest_framework.viewsets import ModelViewSet class BookView(ModelViewSet): queryset = Book.Objects.all() serializer_class = BookSerializer
4.drf之APIView源码分析
4.1 基于APIView的5个接口
序列化类 from rest_framework import serializers from .models import Book class BookSerializer(serializers.ModelSerializer): class Meta: model = Book fields = '__all__' 路由 urlpatterns = [ path('books/', BookView.as_view()), path('books/<int:pk>/', BookDetailView.as_view()), ] 视图类 from rest_framework.views import APIView # APIView继承了django原来的View from .serializer import BookSerializer from rest_framework.response import Response class BookView(APIView): # 查询所有 def get(self,request): book_list = Book.objects.all() # drf提供了序列化类(先别关注) ser = BookSerializer(instance=book_list,many=True) # 序列化 return Response({'code':100,'msg','成功','result':ser.data}) def post(self,request): ser = BookSerializer(data=request.data) # 反序列化 if ser.is_valid(): # 数据校验---》有些不合翻的禁止 ser.save() # 保存到数据库中 return Response({'code': 100, 'msg': '成功'}) class BookDetailView(APIView): # 查询单条 def get(self,request,pk): book = Book.objects.filter(pk=pk).first() ser = BookSerializer(instance=book,many=False) # 序列化 return Response({'code': 100, 'msg': '成功', 'result': ser.data}) # 修改一条 def put(self,request,pk): book = Book.objects.filter(pk=pk).first() ser = BookSerializer(instance=book,data=request.data) #反序列化 if ser.is_valid(): # 数据校验---》有些不合法的禁止 ser.save() # 保存到数据库中 return Response({'code': 100, 'msg': '成功'}) def delete(self,request,pk): Book.objects.filter(pk=pk).delete() return Response({'code': 100, 'msg': '删除成功'})
4.2 CBV源码分析
# cbv写法: 1 视图中写视图类,继承View,写跟请求方式同名的方法 class BookView(View): def get(self,request): return 四件套 2 在路径用写 path('books/', BookView.as_view()) # 前置条件:前端请求,一旦路径匹配成功,就会执行 BookView.as_view()(request传入,) # 入口在 BookView.as_view()--->执行结果---》View中有个as_view类的绑定方法 @classmethod def as_view(cls, **initkwargs): def view(request, *args, **kwargs): self = cls(**initkwargs) res=self.dispatch(request, *args, **kwargs) return res return view # 执行结果是view 的内存地址: 请求来了,执行view(request) path('books/', view) # 执行 View类中的as_view方法中的内层的view函数,路由匹配成功,本质是在执行 self.dispatch(request, *args, **kwargs) # self是谁的对象?BookView的对象 # 去BookView中dispatch,找不到,去父类,View中找到了 # View这个类的dispatch def dispatch(self, request, *args, **kwargs): # request.method.lower() 如果是get请求, ‘get’ 在这个列表里面 if request.method.lower() in self.http_method_names: # handler=getattr(BookView的对象,'get') # handler就是BookView类中的get方法 handler = getattr(self, request.method.lower()) else: handler = self.http_method_not_allowed # 执行 BookView类中的get方法 (request) return handler(request, *args, **kwargs) # 最后结论:什么请求方式,就会执行试图类中的什么方法
4.3 APIView执行流程分析
# 有了drf,后期都写CBV,都是继承APIView及其子类 # 执行流程 入口:path('books/',BookView.as_biew())--->请求来了,执行BookBView.as_view()(request) as_view 先从自己写的类中查找--->再到父类APIView中找 @classmethod def as_view(cls, **initkwargs): view = super().as_view(**initkwargs) # super()代指的是:APIView父类对象 View类的对象 # View的as_view(**initkwargs)----》执行结果是view,是View类的as_view方法中的view view=csrf_exempt(view) # 局部禁用csrf, return view path('books/', View类中的as_view中的view,只是去掉了csrf的认证) 请求来了,执行 【View类的as_view中的view,只是去掉了csrf的认证+(request)调用】 执行:self.dispatch(request, *args, **kwargs) # self是自己写的类的对象 '''self要从根上找 先从自己写的类中找--->再从自己写的类继承的父类APIView中找''' self.dispatch 是APIView中的dispatch,源码如下 def dispatch(self, request, *args, **kwargs): # request是老的request request = self.initialize_request(request, *args, **kwargs) # request是新的request self.request = request try: # 执行了认证,权限和频率 self.initial(request, *args, **kwargs) # 在执行视图类方法之前,去掉了csrf认证,包装了新的request,执行了认证频率和权限 #### 执行请求方式字符串对应的方法 if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) # 无论是在三大认证,还是视图类的方法中,出现错误,都会被异常捕获,统一处理 self.response = self.finalize_response(request, response, *args, **kwargs) return self.response # 总结: 1 以后只要继承APIViwe的所有试图类的方法,都没有csrf的校验了 2 以后只要继承APIView的所有视图类的方法中的request是新的request了 3 在执行试图类的方法之前,执行了三大认证(认证,权限,频率) 4 期间出了各种错误,都会被异常捕获,统一处理
这篇关于drf——restful规范、序列化反序列化、drf介绍和快速使用、drf之APIView源码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15鸿蒙生态设备数量超8亿台
- 2024-05-13TiDB + ES:转转业财系统亿级数据存储优化实践
- 2024-05-09“2024鸿蒙零基础快速实战-仿抖音App开发(ArkTS版)”实战课程已上线
- 2024-05-09聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用
- 2024-05-09log4j2这么配就对了
- 2024-05-09nginx修改Content-Type
- 2024-05-09Redis多数据源,看这篇就够了
- 2024-05-09Google Chrome驱动程序 124.0.6367.62(正式版本)去哪下载?
- 2024-05-09有没有大佬知道这种数据应该怎么抓取呀?
- 2024-05-09这种运行结果里的10.100000001,怎么能最快改成10.1?