REST-framework快速构建API--源码解析
作者:@skyflask
转载本文请注明出处:https://www.cnblogs.com/skyflask/p/10422335.html
目录
一、APIView
二、ModelView
三、认证、权限、频率源码
一、APIView
通过APIView实现API的过程如下:
urls.py
1 2 | url(r '^books/$' , views.BookView.as_view(),name= "books" ), url(r '^books/(\d+)/$' , views.BookDetailView.as_view(),name= "detailbook" ), |
views.py
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 | class BookView(APIView): def get (self, request): book_list = Book.objects.all() bs = BookModelSerializers(book_list, many=True, context={ 'request' : request}) return Response(bs.data) def post(self, request): # post请求的数据 bs = BookModelSerializers(data=request.data) if bs.is_valid(): print(bs.validated_data) bs.save() # create方法 return Response(bs.data) else : return Response(bs.errors) class BookDetailView(APIView): def get (self, request, id): book = Book.objects.filter(pk=id).first() bs = BookModelSerializers(book, context={ 'request' : request}) return Response(bs.data) def put(self, request, id): book = Book.objects.filter(pk=id).first() bs = BookModelSerializers(book, data=request.data, context={ 'request' : request}) if bs.is_valid(): bs.save() return Response(bs.data) else : return Response(bs.errors) def delete(self, request, id): Book.objects.filter(pk=id).delete() return Response() |
1 |
urls中,定义了两个url的请求方式:
-
通过URL:http://127.0.0.1/books/ GET/POST数据
-
通过URL:http://127.0.0.1/books/id/ GET/PUT/DELETE数据
第一种,url(r'^books/$', views.BookView.as_view(),name="books"),调用过程如下:
views.BookView.as_view()
1、APIView.as_view(),返回view,实际上是执行View.as_view()
2、View中的as_view()返回disptch()函数
3、self会从View类往上找dispatch(),在APIView类中有找到dispatch()
4、dispatch()会找get、post、put、delete等方法
5、在当前View下,BookView类下定义了get、post,BookDetailView类下定义了get、put、delete
6、执行当前类下的对应方法
第二种URL执行过程一样。
二、ModelView
通过ModelView实现API过程如下:
urls.py
1 2 | url(r '^authors/$' , views.AuthorModelView.as_view({ 'get' : 'list' , 'post' : 'create' }),name= "authors" ), url(r '^authors/$' , views.AuthorModelView.as_view({ 'get' : 'retrieve' , 'post' : 'update' , 'delete' : 'destory' }),name= "authors" ), |
views.py
1 2 3 4 | class AuthorModelView(viewsets.ModelViewSet): queryset = Author.objects.all() serializer_class = AuthorModelSerializers |
执行过程如下:
1、当前类下没有as_view方法,从父类ModelViewSet中查找
1 |
1 2 3 4 5 6 7 8 9 10 11 | class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): "" " A viewset that provides default `create()`, `retrieve()`, `update()`, `partial_update()`, `destroy()` and `list()` actions. "" " pass |
1 |
2、ModeViewSet在mixins中没有as_view,从GenericViewSet往上找
1 |
1 2 3 4 5 6 7 | class GenericViewSet(ViewSetMixin, generics.GenericAPIView): "" " The GenericViewSet class does not provide any actions by default , but does include the base set of generic view behavior, such as the `get_object` and `get_queryset` methods. "" " pass |
1 |
3、从ViewSetMixin中找到了as_view(),实际上返回了dispatch()
ViewSetMixin==>generics.GenericAPIView==>views.APIView==>dispatch()
4、执行dispatch(),实际上是找get、post、put、delete等方法
5、在当前类下找到对应的方法
三、认证、权限、频率源码
通过ModelView方式实现认证,
局部应用:
1 2 3 4 5 6 | class AuthorModelView(viewsets.ModelViewSet): authentication_classes = [TokenAuth, ] queryset = Author.objects.all() serializer_class = AuthorModelSerializers pagination_class = StandardResultsSetPagination |
全局应用:
1 2 3 4 | REST_FRAMEWORK={ "DEFAULT_AUTHENTICATION_CLASSES" :[ "app01.utils.TokenAuth" ,], } |
源码实现过程:
服务端以authors为例:
1、在AuthorModelView中查找as_view(),在本类中找不到,往上查找;
2、父类:viewsets.ModelViewSet
1 2 3 4 5 6 7 8 9 10 11 | class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, mixins.ListModelMixin, GenericViewSet): "" " A viewset that provides default `create()`, `retrieve()`, `update()`, `partial_update()`, `destroy()` and `list()` actions. "" " pass |
3、其他几个父类没有as_view()和祖父类了,只能从GenericViewSet往上找;
1 2 3 4 5 6 7 | class GenericViewSet(ViewSetMixin, generics.GenericAPIView): "" " The GenericViewSet class does not provide any actions by default , but does include the base set of generic view behavior, such as the `get_object` and `get_queryset` methods. "" " pass |
4、最左边父类ViewSetMixin查找as_view(),找到了
5、ViewSetMixin中的as_veiw()实际上返回了dispatch()
6、再查找dispatch()方法,顺序:generics.GenericAPIView==>APIView==>dispatch()
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 | def dispatch(self, request, *args, **kwargs): "" " `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. "" " self.args = args self.kwargs = kwargs request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? try : self.initial(request, *args, **kwargs) # Get the appropriate handler method 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 |
7、dispatch()中,先会执行self.initial()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def initial(self, request, *args, **kwargs): "" " Runs anything that needs to occur prior to calling the method handler. "" " self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted self.perform_authentication(request) self.check_permissions(request) self.check_throttles(request) |
8、initial()中会对过来的请求进行认证、授权、频率检测。
图标流程如下:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」