django rest framework
一. 什么是RESTful
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
- 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
- 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)
二. RESTful API设计
API与用户的通信协议,总是使用HTTPs协议。
restful 规范(10):
按url来记,从左到右, 然后发送请求,在返回响应
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | 1. 根据method不同,进行不同操作 6 GET / POST / PUT / DELETE / PATCH 2. 面向资源编程 4 使用名词表示资源 http: / / www.luffycity.com / salary 3. 体现版本 3 http: / / www.luffycity.com / v1 / salary http: / / www.luffycity.com / v2 / salary https: / / v4.bootcss.com / https: / / v3.bootcss.com / 4. 体现是API 2 http: / / www.luffycity.com / api / v1 / salary http: / / www.luffycity.com / api / v2 / salary http: / / api.luffycity.com / v1 / salary http: / / api.luffycity.com / v2 / salary 5. https 1 https: / / www.luffycity.com / api / v1 / salary https: / / www.luffycity.com / api / v2 / salary 6. 响应式设置状态码 8 200 300 400 500 return HttpResponse( 'adfasdf' ,status = 300 ) 7. 条件 5 https: / / www.luffycity.com / api / v2 / salary?page = 1 &size = 10 8. 返回值 7 https: / / www.luffycity.com / api / v2 / salary GET: 所有列表 { code: 10000 , data: [ { 'id' : 1 , 'title' : '高亮' }, { 'id' : 1 , 'title' : '龙泰' }, { 'id' : 1 , 'title' : '小东北' }, ] } POST: 返回新增的数据 { 'id' : 1 , 'title' : '高亮' } https: / / www.luffycity.com / api / v2 / salary / 1 / GET: 获取单条数据 { 'id' : 1 , 'title' : '高亮' } PUT:更新 { 'id' : 1 , 'title' : '高亮' } PATCH: 局部更新 { 'id' : 1 , 'title' : '高亮' } DELETE:删除 9. 返回错误信息 9 { code: 100001 , error: 'xxx错误' } 10. Hypermedia API 10 ret = { code: 1000 , data:{ id : 1 , name: '小强' , depart_id:http: / / www.luffycity.com / api / v1 / depart / 8 / } } 建议大家使用restful规范 |
摘自:http://www.ruanyifeng.com/blog/2014/05/restful_api.html
django rest framework框架的作用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | - - - >>> 基于这个组件来帮助我们快速的开发符合restful规范的接口,它是Django里面的一个组件,这个组件为我们提供了以下的功能: - 权限 - 认证 - 访问频率限制 - 序列化 把queryset数据转变为json数据给用户返回. - 路由 - 视图 面试题:你的写的类都继承过哪些类? class View( object ): class APIView(View): class GenericAPIView(views.APIView): class GenericViewSet(ViewSetMixin, generics.GenericAPIView) # ViewSetMixin 是对as_view里面的参数进行处理 class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): - 分页 - 解析器 - 渲染器 - 版本 按照HTTP请求的生命周期去记; 先是进入路由,在视图,进入dispatch()里面,然 后提供的是版本,权限,认证,频率,然后从 解析器()里面取数据,再序列化,分页,渲染器。 |
三. 基于Django实现
路由系统:
1 2 3 | urlpatterns = [ url(r '^admin/' , admin.site.urls), url(r '^books$' , views.BookView.as_view(),name = 'books' )] |
视图函数CBV:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | class BookView(APIView): # def get(self,request): # book_list = Book.objects.all() # # #序列化方式1: 取所有的字段,封装为 列表里面套 字典的形式 # # from django.forms.models import model_to_dict # # # # data=[] # # for obj in book_list: # # data.append(model_to_dict(obj)) # # print(data) # # 序列化方式2: 跟第一种差不多。 # # data = serializers.serialize("json", book_list) # # return HttpResponse(data) # # 序列化方式3: # bs = BookModelSerializers(book_list, many=True,context={'request': request}) # return Response(bs.data) def get( self ,request): return RequestView(Book,BookModelSerializers, self ).get(request) def post( self ,request): # print(request.data) #得到提交的数据,是一个对象 # bs = BookModelSerializers(data=request.data) # many=True是序列化一个querset对象的一个列表; # if bs.is_valid(): # print(bs.validated_data) # bs.save() # return Response(bs.data) # else: # return Response(bs.errors) |
django rest framework的源码流程
按照上面的代码分析:
1.当我们访问请求的时候,将会执行路由系统中的views.BookView.as_view()
2.当前我们自己写的这个类没有as_view()方法,因此会找父类的as_view()方法;即在APIView的as_view()方法
super(APIView,cls)------>为当前父类(view)
super(APIView,cls) 首先找到 APIView的父类(就是类view),然后把 APIView类转换为 view类;
super(APIView,self)------>为当前父类(view)的对象;
3.执行父类view下的as_view()方法:
即通过上面的源码可以知道,当请求来的时候,首先会执行 当前调用as_view()方法的这个类的dispatch方法。
由于我们自己没有写dispatch方法,所以会调用父类的APIView下面的dispatch方法。
4.执行APIView下面的dispatch方法
5.具体执行self.initialize_request(request, *args, **kwargs)的方法
initialize_request是APIView类里面的一个方法,重新封装了request对象,增加了一些属性信息
认证信息。主要通过APIView类中的get_authenticators(rest_framework/views.py)方法获取,这个方法会返回一个所有认证对象的列表
在全局定义的
1 | DEFAULT_AUTHENTICATION_CLASSES |
1 | authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES |
我们自己也可以在自己写的这个views.BookView下自定制一个类属性
1 | authentication_classes = [TokenAuth,] |
TokenAuth
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | from rest_framework import exceptions from rest_framework.authentication import BaseAuthentication from .models import * class TokenAuth(BaseAuthentication): def authenticate( self , request): token = request.GET.get( "token" ) token_obj = Token.objects. filter (token = token).first() if not token_obj: raise exceptions.AuthenticationFailed( "验证失败123!" ) else : return token_obj.user.pk, token_obj.token # def authenticate_header(self, request): # pass # 只是我们继承了BaseAuthentication的认证组件 就不用写了。 |
默认的认证配置信息是在rest_framework/settings.py文件中定义的
6.dispatch中的initialize_request方法执行完成之后,还有执行一个重要方法是self.initial(request, *args, **kwargs),这个方法也是APIView类里的。在这个方法里面初始化
被重新封装的request对象
实现功能:
- 版本处理
- 用户认证
- 权限
- 访问频率限制
版本组件:
执行self.determine_version(request, *args, **kwargs)的结果返回的是一个元组(版本号,版本对象)
版本放在url 里面的用这个类
1 | from rest_framework.versioning import URLPathVersioning |
版本放在url 后面作为参数的用这个类
1 | from rest_framework.versioning import QueryParameterVersioning |
设置版本及获取版本
a. 基于url的get传参方式
1 2 3 4 5 | REST_FRAMEWORK = { 'DEFAULT_VERSION' : 'v1' , # 默认版本 'ALLOWED_VERSIONS' : [ 'v1' , 'v2' ], # 允许的版本 'VERSION_PARAM' : 'version' # URL中获取值的key } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.versioning import QueryParameterVersioning class TestView(APIView): versioning_class = QueryParameterVersioning def get( self , request, * args, * * kwargs): # 获取版本 print (request.version) # 获取版本管理的类 print (request.versioning_scheme) # 反向生成URL reverse_url = request.versioning_scheme.reverse( 'test' , request = request) print (reverse_url) return Response( 'GET请求,响应内容' ) def post( self , request, * args, * * kwargs): return Response( 'POST请求,响应内容' ) def put( self , request, * args, * * kwargs): return Response( 'PUT请求,响应内容' ) |
认证组件:
执行APIView里面的perform_authentication方法,该方法返回request.user,则会调用新封装的Request对象里面的user方法。在user方法里面最终调用了Request类里面的_authenticate方法
执行rest_framework.request.Request类中的_authenticate方法,这个方法会遍历认证类,并根据认证结果给self.user, self.auth赋值。由于user,和auth都有property属性,
所以给赋值的时候先在先执行setter方法
self.authenticators就是包含当前类下面所有的认证组件类的对象的一个列表。遍历列表,执行 对象.authenticate()。
authenticate方法的返回值为一个元组(user_auth_tuple)
1 | self .user, self .auth = user_auth_tuple |
上面其他两个 权限;访问频率限制的原理跟认证是一样的。
7.dispatch中的initial方法执行完之后,会继续判断request.method并执行method相应的method.
8.执行BookView中定义的请求方法,返回数据
Django Rest Framework框架组件的执行流程
1 2 3 | rest framework组件为我们提供了下面的这些功能: 按照HTTP请求的生命周期去记; 先是进入路由,在视图,进入dispatch()里面,然 后提供的是版本,权限,认证,频率,然后从 解析器()里面取数据,再序列化,分页,渲染器。 |
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 对象命名为何需要避免'-er'和'-or'后缀
· SQL Server如何跟踪自动统计信息更新?
· AI与.NET技术实操系列:使用Catalyst进行自然语言处理
· 分享一个我遇到过的“量子力学”级别的BUG。
· Linux系列:如何调试 malloc 的底层源码
· C# 中比较实用的关键字,基础高频面试题!
· .NET 10 Preview 2 增强了 Blazor 和.NET MAUI
· Ollama系列05:Ollama API 使用指南
· 为什么AI教师难以实现
· 如何让低于1B参数的小型语言模型实现 100% 的准确率