Django子函数返回redirect无效:主函数仍执行后续逻辑
Django中视图函数内调用redirect不生效的问题分析与解决
问题根源
你对redirect和异常处理的理解确实存在误区,核心问题出在两点:
- b()的return redirect仅返回对象,不会终止a()执行:b()捕获异常后返回的redirect对象,只是作为函数返回值传递给a(),但a()调用b()时未处理这个返回值,因此会继续执行后续的c()和d(),最终a()自身的return redirect会覆盖b()的返回结果。
- b()内部已捕获异常,不会触发a()的except块:b()的try-except已经处理了
do_something()的异常,所以a()的try块不会捕获到任何异常,自然不会执行a()的except逻辑,流程不会在这里终止。
解决方案
根据需求,有几种可行的调整方式:
方式一:让b()抛出异常,由a()统一处理
修改b(),移除内部的try-except(或捕获异常后重新抛出),让a()的except块捕获异常并终止流程:
def b(request): do_something() messages.success(request, 'I did') def a(request): try: b(request) except Exception: messages.error(request, 'Couldn\'t do the thing') return redirect('namespace:url_name') # 此处return会终止a(),不再执行c和d try: c(request) except Exception: messages.error(request, 'error') return redirect('namespace:url_name') try: d(request) except Exception: messages.error(request, 'error') return redirect('namespace:url_name') return redirect('namespace:url_name')
方式二:a()接收b()的返回值,判断后直接返回
若需保留b()内部的异常处理,a()调用b()时检查返回结果,若为HttpResponseRedirect则直接返回,终止后续流程:
from django.http import HttpResponseRedirect def b(request): try: do_something() messages.success(request, 'I did') except Exception: messages.error(request, 'Couldn\'t do the thing') return redirect('namespace:url_name') def a(request): result = b(request) if isinstance(result, HttpResponseRedirect): return result # 直接返回b()的redirect,终止a()执行 try: c(request) except Exception: messages.error(request, 'error') return redirect('namespace:url_name') try: d(request) except Exception: messages.error(request, 'error') return redirect('namespace:url_name') return redirect('namespace:url_name')
方式三:使用自定义异常标记错误
定义自定义异常,b()在异常时抛出,a()捕获后处理:
class OperationFailed(Exception): pass def b(request): try: do_something() messages.success(request, 'I did') except Exception: messages.error(request, 'Couldn\'t do the thing') raise OperationFailed() def a(request): try: b(request) except OperationFailed: return redirect('namespace:url_name') # 后续c()、d()的处理逻辑同理 return redirect('namespace:url_name')
内容的提问来源于stack exchange,提问作者Abpostman1
相关产品推荐
相关产品推荐

