Django后端相應類設計

通用的ApiResponse類:用于生成統一的 API 響應格式。每個響應都包含以下字段(每個接口最終的返回數據格式):

  • status_code:HTTP 狀態碼(如 200、400、500 等)
  • message:響應的描述信息(如 “Success”、“Resource not found” 等)
  • data:返回的數據(如果有)
  • trace_id:請求的唯一標識符

trace_id的作用:

  • 唯一標識請求:每個請求都有一個唯一的 TraceID
  • 日志關聯:在日志中記錄 TraceID,便于快速定位問題

ApiResponse類核心方法:
1、success 200 請求成功
2、created 201 創建資源成功
3、bad_request 400 后端必要的參數與前端傳遞的參數不一致。例如缺少必填字段、參數類型錯誤(如期望是數字,但傳入了字符串)
4、unauthorized 401 用戶鑒權問題,例如token失效,沒有提供有效的身份驗證信息
5、forbidden 403 禁止訪問,客戶端沒有權限訪問資源
6、not_found 404 請求的資源不存在,URL 路徑錯誤。訪問的 API 路徑錯誤等
7、validation_error 422 請求格式正確,但語義錯誤,服務器無法處理。例如:郵箱格式不正確、密碼長度不符合要求。請求數據不符合業務規則
8、conflict 409 資源沖突,請求與當前資源狀態沖突.例如:創建資源時,資源已存在。用戶重名等
9、internal_server_error 500 服務器內部錯誤,無法完成請求。例如:數據庫連接失敗,代碼邏輯錯誤導致的異常
10、service_unavailable 503 服務不可用,服務器暫時無法處理請求。例如:服務器正在維護,第三方 API 服務失效等

中間件middlewares作用:
Django 中的一個全局異常處理器,它的主要作用是捕獲 Django 視圖函數或中間件中拋出的異常,并根據異常類型返回統一的錯誤響應
同時,它還支持 TraceID 的生成和傳遞,便于追蹤請求的完整調用鏈路。

1、中間件會捕獲所有未處理的異常(包括 Django 內置異常和自定義異常),根據異常類型,生成對應的錯誤響應
2、最終會使用 ApiResponse 類生成統一的錯誤響應格式(status_code、message、data、trace_id)
3、從請求頭中獲取 TraceID,如果未提供則自動生成一個新的。將異常信息和 TraceID 記錄到日志中,便于后續排查問題

整體說明:
1、使用可參考test.py,接口最終返回的數據,需要經過結果處理類ApiResponse,統一進行處理
2、在視圖(接口)中,盡量使用ApiResponse類的10個核心方法,捕捉可能發生的異常
3、中間件會捕捉,代碼未處理的異常,最終規范為status_code、message、data、trace_id四個字段(中間鍵與ApiResponse結果處理類是互補的作用)
4、后端返回的數據,最終會規范為status_code、message、data、trace_id四個字段

class StatusCode:# 成功狀態碼SUCCESS = 200  # 請求成功CREATED = 201  # 創建資源成功# 客戶端錯誤(4XX)BAD_REQUEST = 400  # 參數錯誤UNAUTHORIZED = 401  # 未授權FORBIDDEN = 403  # 禁止訪問NOT_FOUND = 404  # 資源未找到VALIDATION_ERROR = 422  # 參數校驗錯誤CONFLICT = 409  # 資源沖突# 服務端錯誤(5XX)SERVER_ERROR = 500  # 服務器內部錯誤SERVICE_UNAVAILABLE = 503  # 服務不可用class ApiException(Exception):"""基礎異常類,所有自定義異常繼承此類。"""def __init__(self, message, status_code):super().__init__(message)self.status_code = status_codeself.message = message# 客戶端錯誤(4XX)
class BadRequestException(ApiException):"""400 Bad Request"""def __init__(self, message="Bad request"):super().__init__(message, status_code=StatusCode.BAD_REQUEST)class UnauthorizedException(ApiException):"""401 Unauthorized"""def __init__(self, message="Unauthorized"):super().__init__(message, status_code=StatusCode.UNAUTHORIZED)class ForbiddenException(ApiException):"""403 Forbidden"""def __init__(self, message="Forbidden"):super().__init__(message, status_code=StatusCode.FORBIDDEN)class NotFoundException(ApiException):"""404 Not Found"""def __init__(self, message="Resource not found"):super().__init__(message, status_code=StatusCode.NOT_FOUND)class ValidationErrorException(ApiException):"""422 Validation Error"""def __init__(self, message="Validation error"):super().__init__(message, status_code=StatusCode.VALIDATION_ERROR)class ConflictException(ApiException):"""409 Conflict"""def __init__(self, message="Conflict"):super().__init__(message, status_code=StatusCode.CONFLICT)# 服務端錯誤(5XX)
class InternalServerErrorException(ApiException):"""500 Internal Server Error"""def __init__(self, message="Internal server error"):super().__init__(message, status_code=StatusCode.SERVER_ERROR)class ServiceUnavailableException(ApiException):"""503 Service Unavailable"""def __init__(self, message="Service unavailable"):super().__init__(message, status_code=StatusCode.SERVICE_UNAVAILABLE)

以上為自定義的異常處理類,下述為自定義的中間件

import logging
import uuidfrom django.core.exceptions import PermissionDenied
from django.http import Http404from 響應類設計.exceptions import *
from 響應類設計.response_handler import ApiResponselogger = logging.getLogger(__name__)class ExceptionHandlingMiddleware:def __init__(self, get_response):self.get_response = get_responsedef __call__(self, request):# 從請求頭中獲取 Trace ID,如果沒有則生成一個新的trace_id = request.headers.get('X-Trace-ID', str(uuid.uuid4()))request.trace_id = trace_id  # 將 Trace ID 綁定到請求對象try:response = self.get_response(request)return responseexcept Exception as e:return self.handle_exception(e, trace_id)def handle_exception(self, exception, trace_id):# 記錄異常日志,包含 Trace IDlogger.error(f"Trace ID: {trace_id}, Error: {str(exception)}", exc_info=True)if isinstance(exception, Http404):return ApiResponse.not_found(message=str(exception), trace_id=trace_id)elif isinstance(exception, PermissionDenied):return ApiResponse.forbidden(message=str(exception), trace_id=trace_id)elif isinstance(exception, BadRequestException):return ApiResponse.bad_request(message=str(exception), trace_id=trace_id)elif isinstance(exception, UnauthorizedException):return ApiResponse.unauthorized(message=str(exception), trace_id=trace_id)elif isinstance(exception, ForbiddenException):return ApiResponse.forbidden(message=str(exception), trace_id=trace_id)elif isinstance(exception, NotFoundException):return ApiResponse.not_found(message=str(exception), trace_id=trace_id)elif isinstance(exception, ValidationErrorException):return ApiResponse.validation_error(message=str(exception), trace_id=trace_id)elif isinstance(exception, ConflictException):return ApiResponse.conflict(message=str(exception), trace_id=trace_id)elif isinstance(exception, InternalServerErrorException):return ApiResponse.internal_server_error(message=str(exception), trace_id=trace_id)elif isinstance(exception, ServiceUnavailableException):return ApiResponse.service_unavailable(message=str(exception), trace_id=trace_id)else:# 未知異常,返回 500 狀態碼return ApiResponse.internal_server_error(message="An unexpected error occurred.", trace_id=trace_id)
from django.http import JsonResponse
import uuidfrom 響應類設計.exceptions import StatusCodeclass ApiResponse:"""通用的 API 響應類,支持 Trace ID 和多種狀態碼。"""def __init__(self, status_code, message, data=None, trace_id=None):self.status_code = status_codeself.message = messageself.data = dataself.trace_id = trace_id or str(uuid.uuid4())  # 生成唯一的 Trace IDdef to_dict(self):"""將響應數據轉換為字典格式。"""return {'status_code': self.status_code,'message': self.message,'data': self.data if self.data is not None else {},'trace_id': self.trace_id  # 包含 Trace ID}def to_json_response(self):"""將響應數據轉換為 Django 的 JsonResponse。"""return JsonResponse(self.to_dict(), status=self.status_code)# 成功響應@staticmethoddef success(message="Success", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.SUCCESS, message=message, data=data,trace_id=trace_id).to_json_response()# 資源創建成功@staticmethoddef created(message="Resource created", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.CREATED, message=message, data=data,trace_id=trace_id).to_json_response()# 客戶端錯誤@staticmethoddef bad_request(message="Bad request", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.BAD_REQUEST, message=message, data=data,trace_id=trace_id).to_json_response()@staticmethoddef unauthorized(message="Unauthorized", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.UNAUTHORIZED, message=message, data=data,trace_id=trace_id).to_json_response()@staticmethoddef forbidden(message="Forbidden", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.FORBIDDEN, message=message, data=data,trace_id=trace_id).to_json_response()@staticmethoddef not_found(message="Resource not found", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.NOT_FOUND, message=message, data=data,trace_id=trace_id).to_json_response()@staticmethoddef validation_error(message="Validation error", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.VALIDATION_ERROR, message=message, data=data,trace_id=trace_id).to_json_response()@staticmethoddef conflict(message="Conflict", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.CONFLICT, message=message, data=data,trace_id=trace_id).to_json_response()# 服務端錯誤@staticmethoddef internal_server_error(message="Internal server error", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.SERVER_ERROR, message=message, data=data,trace_id=trace_id).to_json_response()@staticmethoddef service_unavailable(message="Service unavailable", data=None, trace_id=None):return ApiResponse(status_code=StatusCode.SERVICE_UNAVAILABLE, message=message, data=data,trace_id=trace_id).to_json_response()

上述為定義的結果處理類,一下為使用說明案例

from django.views import View
import uuid
from .exceptions import BadRequestException, NotFoundException
from .response_handler import ApiResponsedef get_trace_id(request):"""從請求頭中獲取 Trace ID,如果沒有則生成一個新的。"""return request.headers.get('X-Trace-ID', str(uuid.uuid4()))class MyView(View):def get(self, request, *args, **kwargs):"""示例 GET 請求視圖,展示如何使用 Trace ID。"""# 獲取或生成 Trace IDtrace_id = get_trace_id(request)# 示例:從 URL 參數中獲取資源 IDresource_id = kwargs.get('resource_id')if not resource_id:# 如果資源 ID 不存在,返回 400 錯誤raise BadRequestException("Resource ID is required.")# 模擬資源查找resource = self.get_resource(resource_id)if not resource:# 如果資源未找到,返回 404 錯誤raise NotFoundException("Resource not found.")# 返回成功響應return ApiResponse.success(message="Resource retrieved successfully",data=resource,trace_id=trace_id)def post(self, request, *args, **kwargs):"""示例 POST 請求視圖,展示如何使用 Trace ID。"""# 獲取或生成 Trace IDtrace_id = get_trace_id(request)# 示例:從請求體中獲取數據data = request.POSTif not data.get('name'):# 如果名稱字段不存在,返回 400 錯誤raise BadRequestException("Name is required.")# 模擬創建資源resource = self.create_resource(data)return ApiResponse.created(message="Resource created successfully",data=resource,trace_id=trace_id)def get_resource(self, resource_id):"""模擬資源查找邏輯。"""# 這里可以替換為實際的數據庫查詢邏輯if resource_id == "123":return {"id": "123", "name": "Example Resource"}return Nonedef create_resource(self, data):"""模擬資源創建邏輯。"""# 這里可以替換為實際的數據庫插入邏輯return {"id": str(uuid.uuid4()), "name": data.get('name')}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65782.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65782.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65782.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

汽車基礎軟件AutoSAR自學攻略(三)-AutoSAR CP分層架構(2)

汽車基礎軟件AutoSAR自學攻略(三)-AutoSAR CP分層架構(2) 下面我們繼續來介紹AutoSAR CP分層架構,下面的文字和圖來自AutoSAR官網目前最新的標準R24-11的分層架構手冊。該手冊詳細講解了AutoSAR分層架構的設計,下面讓我們來一起學習一下。 Introductio…

css面試常考布局(圣杯布局、雙飛翼布局、三欄布局、兩欄布局、三角形)

兩欄布局 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head> &…

模糊查詢在sqlserver、dm8、mysql的編寫示例

模糊查詢要求&#xff1a;字段值以 25D 開頭&#xff0c;并以 4 位數字結尾 sqlserver&#xff1a; select * from table_name where column_name like 25D[0-9][0-9][0-9][0-9] 說明&#xff1a; 25D&#xff1a;表示字符串以 25D 開頭。 [0-9][0-9][0-9][0-9]&#xf…

SCTNet模型詳解及代碼復現

模型背景 隨著深度學習技術的發展,語義分割領域取得了顯著進展。然而,在實際應用中,特別是在實時場景下,現有模型往往面臨計算復雜度高、難以平衡精度和速度等問題。為應對這些挑戰,研究人員提出了SCTNet模型,旨在解決實時語義分割問題,同時兼顧精度和效率。該模型融合…

Python的循環

Python的循環 Python的循環有兩種&#xff0c;分別是for…in循環和while循環。 for…in 循環 假設我們要循環輸出一個列表里的元素&#xff1a; names [張三,李四,王五] for name in names:print(name)執行這段代碼后&#xff0c;會依次打印names的每一個元素&#xff1a;…

【0387】Postgres內核 streaming replication(流復制)工作原理

1. Postgres 流復制 本文是關于設置 PostgreSQL 版本流復制的簡明指南,力求盡可能不受平臺限制。故而,其假定您擁有運用操作系統工具編輯文件及安裝/配置軟件包的扎實知識。并且,還假定您熟悉 PostgreSQL 的配置情況。 PostgreSQL 內置的流復制為您的數據庫構建了一個服務…

網絡攻擊行為可視化分析系統【數據分析 + 可視化】

一、系統背景 隨著信息技術的快速發展&#xff0c;網絡已成為現代社會不可或缺的一部分。然而&#xff0c;與此同時&#xff0c;網絡攻擊手段也日益多樣化和復雜化&#xff0c;給企業和個人的信息安全帶來了極大的威脅。傳統的網絡攻擊分析方法往往依賴于人工分析和處理大量的…

利用obs studio制作(人像+屏幕)錄制影像

1.什么是obs? OBS&#xff08;Open Broadcaster Software&#xff09;是一款功能強大的開源軟件&#xff0c;它使用戶能夠直接從電腦錄制視頻和直播內容到 Twitch&#xff0c;YouTube 和 Facebook Live 等平臺。它在需要直播或錄制屏幕活動的游戲玩家、YouTube 用戶和專業人士…

蠕蟲病毒會給服務器造成哪些危害?

蠕蟲病毒是一種獨立的惡意計算機程序&#xff0c;可以進行自我復制來傳播到其他的計算機系統當中&#xff0c;蠕蟲病毒和傳統病毒之間是有著區別的&#xff0c;蠕蟲病毒不需要宿主程序就能夠自行傳播&#xff0c;主要是利用各種操作系統漏洞進行攻擊的。 接下來小編就介紹一下蠕…

C# GDI+的DrawString無法繪制Tab鍵的現象

【啰嗦2句】 現在用C#的人很少了吧&#xff1f;GDI更少了吧&#xff1f;所以這個問題估計也冷門。沒關系&#xff0c;分享給特定需要的人也不錯。 【問題現象】 工作中開發了一個報告編輯器&#xff0c;實現圖文排版等功能&#xff0c;用著沒什么問題&#xff0c;直到有一天…

互斥信號量的等待與通知

目錄 等待互斥信號量 信號量未被占用 信號量被自己占用 信號量被高優先級任務占用 信號量被低優先級任務占用 釋放互斥信號量 未發生優先級繼承 發生優先級繼承 等待互斥信號量 信號量未被占用 標記為已經被占用鎖定計數1 信號量被自己占用 鎖定計數1 信號量被高優先級任務占用…

夯實前端基礎之HTML篇

知識點概覽 HTML部分 1. DOM和BOM有什么區別&#xff1f; DOM&#xff08;Document Object Model&#xff09; 當網頁被加載時&#xff0c;瀏覽器會創建頁面的對象文檔模型&#xff0c;HTML DOM 模型被結構化為對象樹 用途&#xff1a; 主要用于網頁內容的動態修改和交互&…

Qt資源文件以及文件加密

1、Qt資源文件 在Qt中&#xff0c;資源文件&#xff08;.qrc&#xff09;是一種方便的方式來管理應用程序中的多媒體文件&#xff0c;如圖像、圖標和其他資源。這些文件使用XML格式定義&#xff0c;并在編譯時嵌入到應用程序的二進制文件中。 創建資源文件的步驟如下&#xff…

深入詳解人工智能自然語言處理(NLP)之文本處理:分詞、詞性標注、命名實體識別

【自然語言處理】——深入詳解人工智能自然語言處理&#xff08;NLP&#xff09;之文本處理&#xff1a;分詞、詞性標注、命名實體識別 自然語言處理&#xff08;Natural Language Processing&#xff0c;簡稱NLP&#xff09;是人工智能的一個重要分支&#xff0c;涉及如何使計…

SD ComfyUI工作流 老照片修復上色

文章目錄 老照片修復上色SD模型Node節點工作流程開發與應用效果展示老照片修復上色 該工作流專門設計用于老照片的修復和上色,通過一系列高級的圖像處理技術,包括深度圖預處理、面部修復、上色和圖像放大等步驟,來恢復老照片的質量并增加色彩。首先,工作流加載老照片并進行…

后端技術選型 sa-token校驗學習 下 結合項目學習 前后端登錄

目錄 后端設置 Controller 層 Service 層 后端返回 Token 給前端 1. 用戶提交登錄請求 2. 后端驗證用戶身份 3. 返回 Token 4. 前端保存 Token 前端存儲 1. 前端向后端發起請求 2. 前端存儲一下 Token 3.管理用戶認證的 token 的 工具 4. 在 Service 層進行設置 H…

dtdug匯編指令練習

r 通用寄存器 m 代表內存 imm 代表立即數 r8 代表8位通用寄存器 m8 代表8位內存 imm8 代表8位立即數 mov指令練習 MOV 的語法: mov 目標操作數&#xff0c;源操作數 作用:拷貝源操作數到目標操作數 1、源操作數可以是立即數、通用寄存器、段寄存器、或者內存單元. 2、目標操作數…

vue3模板引用ref

1.訪問模板引用 要在組合式 API 中獲取引用&#xff0c;我們可以使用輔助函數 useTemplateRef() 只可以在組件掛載后才能訪問模板引用 <script setup> import { useTemplateRef, onMounted } from vue// 第一個參數必須與模板中的 ref 值匹配 const input useTempla…

如何用 SSH 訪問 QNX 虛擬機

QNX 虛擬機默認是開啟 SSH 服務的&#xff0c;如果要用 SSH 訪問 QNX 虛擬機&#xff0c;就需要知道虛擬機的 IP 地址&#xff0c;用戶和密碼。本文我們來看看如何獲取這些參數。 1. 啟動虛擬機 啟動過程很慢&#xff0c;請耐心等待。 2. 查看 IP 地址 等待 IDE 連接到虛擬機。…

【Java基礎】Java異常捕捉,throws/throw、finally、try、catch關鍵字的含義與運用

1. Java 異常處理&#xff1a; 異常是程序中的一些錯誤&#xff0c;但并不是所有的錯誤都是異常&#xff0c;并且錯誤有時候是可以避免的。 比如說&#xff0c;你的代碼少了一個分號&#xff0c;那么運行出來結果是提示是錯 java.lang.Error&#xff1b;如果你用System.out.p…