如何在Django Admin中遇到异常时执行重试操作?
Django Admin操作异常重试实现方案
核心思路
通过重写ModelAdmin中对应增删改操作的方法,在方法内部捕获指定异常(如数据库连接异常、网络异常等),嵌入重试逻辑;针对批量删除场景,需替换默认的批量处理动作来实现重试。
具体实现步骤
1. 定义通用重试装饰器
先写一个可复用的重试装饰器,避免在多个方法中重复编写重试逻辑:
# "store/admin.py" import time from functools import wraps from django.db import OperationalError # 可根据实际需要扩展捕获的异常类型 def retry_on_exception(max_retries=3, delay=1, exceptions=(OperationalError,)): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): retries = 0 while retries < max_retries: try: return func(*args, **kwargs) except exceptions as e: retries += 1 if retries == max_retries: raise # 达到最大重试次数,抛出原异常让Admin显示错误页 time.sleep(delay) # 重试间隔 return wrapper return decorator
2. 重写PersonAdmin的操作方法
针对你提到的四个场景,分别重写对应的Admin方法:
# "store/admin.py" from django.contrib import admin from django.contrib.admin.actions import delete_selected from django.http import HttpResponseRedirect from .models import Person @admin.register(Person) class PersonAdmin(admin.ModelAdmin): # 场景1:添加数据、场景2:修改数据 统一处理 @retry_on_exception(max_retries=3, delay=1) def save_model(self, request, obj, form, change): super().save_model(request, obj, form, change) # 场景3:修改页面删除单个数据 @retry_on_exception(max_retries=3, delay=1) def delete_model(self, request, obj): super().delete_model(request, obj) # 场景4:批量删除数据 def get_actions(self, request): actions = super().get_actions(request) # 替换默认的批量删除动作,加入重试逻辑 if 'delete_selected' in actions: actions['delete_selected'] = (self.retry_delete_selected, 'delete_selected', actions['delete_selected'][2]) return actions @retry_on_exception(max_retries=3, delay=1) def retry_delete_selected(self, request, queryset): return delete_selected(self, request, queryset) # 确保批量删除重试失败后页面正常跳转 def response_action(self, request, queryset): try: return super().response_action(request, queryset) except Exception: return HttpResponseRedirect(request.path)
关键说明
- 异常范围可自定义:装饰器的
exceptions参数可以添加其他需要捕获的异常类型,比如ConnectionError。 - 重试参数可调整:
max_retries(最大重试次数)和delay(重试间隔秒数)可根据业务需求修改。 - 重试失败后仍保留原异常:达到最大重试次数后会抛出原异常,Django Admin会正常显示你截图中的错误页面,不会静默忽略问题。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

