全局异常处理,media访问

全局异常封装处理

概述:

  • 当我们在处理request请求时,前端接受的格式都要统一,无论后端是否出错
  • 自内部调用一些函数做一些遗产给处理的时候,还是可能就会出现一些处理不到的错,造成程序不能正常运行,甚至会导致直接将报错返回到前端
  • 为了避免这一错误,使我们的后端服务看起来是正常运行的,就算是报错也会返回一个前端一个提示,以及在后端做一些错误信息的日志记录,这里我们引入 全局异常处理
项目在运行的过程中,走到三大认证,视图类的方法只要出现了异常,就会执行一个函数,但是这个函数只能处理drf的异常,这时我们就需要自己重写一个函数,既能处理drf的异常,又能处理django的异常,这样统一返回格式,前端看到的格式也是统一的

使用步骤:
	1.utils 文件中新建一个common_exceptions.py
  	2.写一个函数
    	项目代码 (下文)
        
    3.配置配置文件,以后只要除了异常就走自己写的函数
    REST_FRAMEWORK = {
            'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler',
        }
    
    4. 以后在写带的时候,不要怕代码报错,程序不会蹦,并且会记录日志,处理成统一的格式

代码:

common_exceptions.py

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response

from utils.common_logger import logger

# 一般只要走到这个函数,就一定是除了异常,所以需要记录日志
def exception_handler(exc,context):
    # 记录日志:IP地址,用户id 访问路径,执行函数,报错信息
    request=context.get('request')
    view=context.get('view')
    ip=request.META.get('REMOTE_ADDR')
    user_id=request.user.pk
    path=request.get_full_path()
    response=drf_exception_handler(exc,context)
    if response:
        logger.warning('drf出了异常,异常是:%s'%str(exc))
        # drf 的异常已经处理了,直接取detail 会有一点小小的问题,(获取出现再解决)
        res =Response({'code':1000,'msg':response.data.get('detail','服务器异常,请联系系统管理员')})
    else:
        # 这是django的异常
        logger.error(f'用户{user_id},IP地址{ip},访问 地址{path},执行函数{str(view)},{str(exc)}')
        res=Response({'code':1001,'msg':'服务器异常,请联系管理员'})
    return res

封装Response

# 本身的drf 是有Response的,但是一般都会规定前端收到的数据格式必须是固定的
	{'code':100,'msg':'提示信息',data:{}/[]}
    
所以我们将Response进行封装,封装过后,code,msg 这些写是可以不用传的,不传的话就使用默认的

使用的步骤:
	1.在 utils 下创建common_response.py
    2.封装APIResponse
    3.导入使用,视图函数的方法,返回时,使用的都是自己的

代码

from rest_framework.response import Response

class APIResponse(Response):
    def __init__(self,code=100,msg='成功',status=None,headers=None,**kwargs):
        data={'code':code,'msg':msg}
        if kwargs:
            # 如果有值的话就说明传进来数据,是除了code,msg,status,headers 之外的数据,这些都是要返回给前端的,所以要将它们放在data
            data.update(kwargs)
        super().__init__(data=data,status=status,headers=headers)

开启media的访问

# 配置文件加入
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# 总路由中设置
# re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT})
# 访问
http://127.0.0.1:8000/media/icon/default.png
        
        
# 以后使用djagno的配置文件都用这个
from django.conf import settings
posted @ 2023-02-28 08:18  亓官扶苏  阅读(30)  评论(0)    收藏  举报