亚洲精品久久久中文字幕-亚洲精品久久片久久-亚洲精品久久青草-亚洲精品久久婷婷爱久久婷婷-亚洲精品久久午夜香蕉

您的位置:首頁技術文章
文章詳情頁

Django REST framework 異常處理

瀏覽:3日期:2024-09-03 16:58:22
目錄寫在前面DRF異常處理1. DRF 常見的異常2. 自定義異常3. 使用自定義異常4. 驗證結果異常處理進階1. 修改自定義異常2. 自定義更多異常3. 新增測試接口4. 驗證結果總結參考資料寫在前面

這兩天一直在思索關于 DRF 還有哪些是項目必備的而且還沒有說到的基礎性的知識。這不昨天寫到日志相關的功能就直接想到還有異常處理相關的功能,其實在之前項目中初期是沒有統一的異常捕獲手段。可能是 DRF 自帶的異常 能滿足大多數功能,也可能是比較懶,就使用比較粗暴的方式,以狀態碼 500 的方式去拋出異常,然后在日志中可以看到所有的異常信息。這么做呢,代碼其實是不夠健壯的,前端在調用的時候莫名的 500 也是不夠友好的,所以今天就補充一下異常相關的知識。

DRF異常處理1. DRF 常見的異常 AuthenticationFailed/ NotAuthenticated 一般該異常狀態碼為'401 Unauthenticated',主要是沒有登錄鑒權的時候會返回,可以用在自定義登錄的時候。 PermissionDenied 一般用在鑒權時候使用,一般狀態碼為'403 Forbidden'。 ValidationError 一般狀態碼為'400 Bad Request',主要是 serializers 中對字段的校驗,比如對字段類型的校驗、字段長度的校驗以及自定義字段格式的校驗。2. 自定義異常

這里對異常的定義主要的想法來自 ValidationError,統一異常返回的格式,方便前端統一處理類似異常。

自定義異常

# 新建 utils/custom_exception.pyclass CustomException(Exception): _default_code = 400 def __init__(self,message: str = '',status_code=status.HTTP_400_BAD_REQUEST,data=None,code: int = _default_code, ):self.code = codeself.status = status_codeself.message = messageif data is None: self.data = {'detail': message}else: self.data = data def __str__(self):return self.message

自定義異常處理

# utils/custom_exception.pyfrom rest_framework.views import exception_handlerdef custom_exception_handler(exc, context): # Call REST framework’s default exception handler first, # to get the standard error response.# 這里對自定義的 CustomException 直接返回,保證系統其他異常不受影響 if isinstance(exc, CustomException):return Response(data=exc.data, status=exc.status) response = exception_handler(exc, context) return response

配置自定義異常處理類

REST_FRAMEWORK = { # ... 'EXCEPTION_HANDLER': 'utils.custom_exception.custom_exception_handler',}3. 使用自定義異常

使用之前文章的接口用來測試自定義異常的處理

class ArticleViewSet(viewsets.ModelViewSet): ''' 允許用戶查看或編輯的API路徑。 ''' queryset = Article.objects.all() serializer_class = ArticleSerializer @action(detail=False, methods=['get'], url_name='exception', url_path='exception') def exception(self, request, *args, **kwargs):# 日志使用 demologger.error('自定義異常')raise CustomException(data={'detail': '自定義異常'})4. 驗證結果

$ curl -H ’Accept: application/json; indent=4’ -u admin:admin http://127.0.0.1:8000/api/article/exception/{ 'detail': '自定義異常'}異常處理進階

上面的代碼雖說是可以滿足90%的需求,但是錯誤的定義太泛泛。難以集中定義管理錯誤,與常見項目中自定義的異常比較優點就是靈活,但是隨著代碼中拋出的異常越來越多加之散落在各個角落,不利于更新維護。所以下面對修改一下代碼,對異常有統一的定義,同時也支持自定義返回HTTP狀態碼。

1. 修改自定義異常

# utils/custom_exception.pyclass CustomException(Exception): # 自定義code default_code = 400 # 自定義 message default_message = None def __init__( self, status_code=status.HTTP_400_BAD_REQUEST, code: int = None, message: str = None, data=None, ):self.status = status_codeself.code = self.default_code if code is None else codeself.message = self.default_message if message is None else messageif data is None: self.data = {'detail': self.message, 'code': self.code}else: self.data = data def __str__(self):return str(self.code) + self.message2. 自定義更多異常

class ExecuteError(CustomException): '''執行出錯''' default_code = 500 default_message = '執行出錯'class UnKnowError(CustomException): '''執行出錯''' default_code = 500 default_message = '未知出錯'3. 新增測試接口

class ArticleViewSet(viewsets.ModelViewSet): ''' 允許用戶查看或編輯的API路徑。 ''' queryset = Article.objects.all() serializer_class = ArticleSerializer @action(detail=False, methods=['get'], url_name='exception', url_path='exception') def exception(self, request, *args, **kwargs):# 日志使用 demologger.error('自定義異常')raise CustomException(data={'detail': '自定義異常'}) @action(detail=False, methods=['get'], url_name='unknown', url_path='unknown') def unknown(self, request, *args, **kwargs):# 日志使用 demologger.error('未知錯誤')raise UnknownError() @action(detail=False, methods=['get'], url_name='execute', url_path='execute') def execute(self, request, *args, **kwargs):# 日志使用 demologger.error('執行錯誤')raise ExecuteError()4. 驗證結果

curl -H ’Accept: application/json; indent=4’ -u admin:admin http://127.0.0.1:8000/api/article/unknown/{ 'detail': '未知出錯', 'code': 500}$ curl -H ’Accept: application/json; indent=4’ -u admin:admin http://127.0.0.1:8000/api/article/execute/{ 'detail': '執行出錯', 'code': 500}總結

需要注意自定義的異常處理函數需要在處理完成自定義異常后繼續執行 rest_framework.views.exception_handler,因為這里的執行仍然需要兼容已有的異常處理;下面貼一下 DRF 有關的異常處理邏輯。

該處理函數默認處理 APIException以及 Django 內部的 Http404 PermissionDenied,其他的異常會返回 None ,會觸發 DRF 500 的錯誤。

def exception_handler(exc, context): ''' Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django’s built-in `Http404` and `PermissionDenied` exceptions. Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. ''' if isinstance(exc, Http404):exc = exceptions.NotFound() elif isinstance(exc, PermissionDenied):exc = exceptions.PermissionDenied() if isinstance(exc, exceptions.APIException):headers = {}if getattr(exc, ’auth_header’, None): headers[’WWW-Authenticate’] = exc.auth_headerif getattr(exc, ’wait’, None): headers[’Retry-After’] = ’%d’ % exc.waitif isinstance(exc.detail, (list, dict)): data = exc.detailelse: data = {’detail’: exc.detail}set_rollback()return Response(data, status=exc.status_code, headers=headers) return None參考資料

Django REST framework 異常文檔Django 異常文檔

到此這篇關于Django REST framework 異常處理的文章就介紹到這了,更多相關Django REST framework 異常內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Django
相關文章:
主站蜘蛛池模板: 久久99九九精品免费 | 成人黄色一级片 | 欧美日韩综合精品一区二区三区 | 成人涩| 国产丝袜啪啪 | 国产高清视频在线观看不卡v | 欧美亚洲国产日韩一区二区三区 | 日本一级特黄毛片高清视频 | 青青青国产色视频在线观看 | 久99频这里只精品23热 视频 | 99视频精品全部国产盗摄视频 | 九一国产精品 | 国产成人精品免费久久久久 | 日韩黄色网 | 亚欧黄色 | 免费国产视频在线观看 | 国产婷婷一区二区在线观看 | 美女隐私视频黄www免费 | 亚洲国产成人最新精品资源 | 亚洲欧美精选 | 精品福利视频在线观看视频 | 国产精品欧美日韩一区二区 | 1717she精品国产真正免费 | 色网综合 | 国产码一区二区三区 | 亚洲玖玖 | 色一情一乱一乱91av | 国产又色又爽在线观看 | 国产成人精品日本亚洲麻豆 | 一级无毛片 | 狠狠操影院 | 黄色大片在线播放 | a级国产乱理论片在线观看看 | 可以直接看黄的网站 | 欧美日本一道高清二区三区 | 欧美中文字幕在线视频 | 国产精品视频一区二区三区 | 国产免费拍拍视频在线观看网站 | 欧美一级高清片欧美国产欧美 | 国产精品久久国产三级国不卡顿 | 日本特黄特色aaa大片免费欧 |