• 六、python Django REST framework修改源码[更改restful接口风格、访问错误的响应]


    django 3.2.13

    一、修改源码更改restful接口风格

    1、View

    解释:单纯继承View可以用以下方法

    修改文件的导入地址:from django.views.generic.base import View
    修改文件的地址:Python38\Lib\site-packages\django\views\generic\base.py

    修改前的代码:

    class View:
    	...
        def dispatch(self, request, *args, **kwargs):
        	'''
        		该dispatch英语意思就是分发,在代码中也是如此,源码根据请求方式的不用,把其分发给我们程序员自定义的函数
        		如此我们便可以根据此特点更改其代码
        	'''
            if request.method.lower() in self.http_method_names:
            	'''
            	request.method.lower()就是请求方式,self.http_method_names就是一个存放者类似get,post请求的列表
            	'''
                handler = getattr(self,request.method.lower(),self.http_method_not_allowed)
                '''
                getattr函数通过第二个参数去self里面寻找(其实就是找程序员定义的get(),post()这类方法)
                找到就返回一个内存地址,找不到就执行第三个参数
                关键点就在这里,它根据请求名字不同找对应的方法,我们就可以在这里修改源码,该为自己的风格
                '''
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
        ...
        	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    修改后的代码:

    本代码接口风格:单纯不想使用get、post以外的请求,但又想让代码整齐,继续根据功能写get()、post()、put()函数,例如想使用get以外的请求,就专门通过post请求携带一个参数(指的是数据要干什么,比如更新就写put,删除写delete)

    class View:
    	...
        def dispatch(self, request, *args, **kwargs):
            import json
            if request.method.lower() in self.http_method_names:
            # 代码修改开始区域
                if request.method.lower() == 'get':
                    attr = request.method.lower()
                elif request.method.lower() == 'post':
                    post = json.loads(request.body)
                    attr = post.get("flag")
                else:
                    handler = self.http_method_not_allowed
                # handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                handler = getattr(self, attr, self.http_method_not_allowed)
            # 代码修改结束区域
            else:
                handler = self.http_method_not_allowed
            return handler(request, *args, **kwargs)
        ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2、APIView

    使用范围:只要继承了APIView的都能使用,几乎只要不是单单继承View的都可以用,APIView在这里把它继承的View里面的as_view重写

    修改文件的导入地址:from rest_framework import APIView
    修改文件的地址:\Python38\Lib\site-packages\rest_framework\views.py

    修改前的代码:

        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?
            print(self.args,self.kwargs,self.headers)
            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
    
    • 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

    修改后的代码:

    本代码接口风格:单纯不想使用get、post以外的请求,但又想让代码整齐,继续根据功能写get()、post()、put()函数,例如想删除,就专门通过post请求携带一个{'flag':'delete'}参数,然后dispatch就会去寻找delete()函数

        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?
            print(self.args,self.kwargs,self.headers)
            try:
                self.initial(request, *args, **kwargs)
    
                # Get the appropriate handler method
                import json
                if request.method.lower() in self.http_method_names:
                # 代码修改开始区域
                    # handler = getattr(self, request.method.lower(),
                    #                   self.http_method_not_allowed)
                    if request.method.lower() == 'get':
                        attr = request.method.lower()
                    elif request.method.lower() == 'post':
                        post = json.loads(request.body)
                        attr = post.get("flag")
                    else:
                        handler = self.http_method_not_allowed
                    handler = getattr(self, attr, 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
    • 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

    二、修改源码访问错误的响应

    源码地址:rest_framework\exceptions.py

    解释:这里的许多类都是报错来调用的,django rest接受到报错,然后返回状态码

    示例(限流):

    1. def dispatch(self, request, *args, **kwargs)分发过程中到这个self.initial(request, *args, **kwargs)
    2. 在initial函数里面有一个self.check_throttles(request)(这是限流逻辑代码)
    3. check_throttles函数第359if not throttle.allow_request(request, self)判断是否需要被限制,需要被限制就算出解除时间添加到列表
    4. 362if throttle_durations:通过判断列表是否为空就知道是否需要进行报错,然后返回错误信息,
    5. 此时就可以知道通过exceptions.py的修改就能更改,django rest返回给用户的信息
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    CocosCreator-常见问题和解决-持续更新
    NFT,还是有未来的
    JavaFX Scene Builder Menu 控件详解
    【深度学习实战(25)】搭建训练框架之ModelEMA
    实战SRC
    c语言练习题56:变种水仙花
    深入理解XGBoost:集成学习与堆叠模型
    暮光壁纸(安卓)
    Leetcode.322-零钱兑换(动态规划)
    备战金九银十,这份分布式架构文档:ZK+高可用+缓存+事务+中间件绝了
  • 原文地址:https://blog.csdn.net/weixin_46765649/article/details/126201504