Django Context Processor报AnonymousUser不可迭代问题解决问询
问题1:未调用上下文变量为什么处理器仍会执行
Django的全局上下文处理器执行逻辑和模板是否调用返回变量无关。只要你将该处理器配置到了settings.py的TEMPLATES.OPTIONS.context_processors列表中,所有使用RequestContext渲染模板的视图,都会在渲染前按顺序执行所有注册的上下文处理器,收集所有返回的上下文变量合并后再传给模板,不管你最终有没有在模板里使用这些变量。这就是登录页即使没用到Calicount也会触发函数执行的原因。
问题2:上下文处理器层面实现指定视图不调用的方案
方案1:在处理器内部增加逻辑判断,跳过不需要执行的场景
这是改造成本最低的方案,你可以先判断用户登录状态解决当前报错,再按需排除指定视图:
基础版:仅修复未登录报错
def subject_renderer(request): # 未登录用户直接返回空字典,不执行查询逻辑 if request.user.is_authenticated: return { "Calicount": Tools_Calibrated.objects.filter( user=request.user, calibrated=True, issued=True ).count(), } return {}
进阶版:排除指定视图
可以通过请求路径、视图名称两种方式过滤不需要执行的视图:
def subject_renderer(request): # 按路径排除,示例为登录页路径,可按需添加其他路径 excluded_paths = ["/accounts/login/"] if request.path in excluded_paths: return {} # 按视图名排除,示例为登录视图的命名,可按需添加其他视图名 if request.resolver_match: excluded_view_names = ["account_login"] if request.resolver_match.view_name in excluded_view_names: return {} # 剩余场景走原有逻辑 if request.user.is_authenticated: return { "Calicount": Tools_Calibrated.objects.filter( user=request.user, calibrated=True, issued=True ).count(), } return {}
方案2:取消全局注册,按需注入上下文
如果只有少量视图需要用到Calicount变量,更推荐放弃全局上下文处理器,改为公共函数按需调用,从根源上避免无关视图触发执行:
# 公共工具函数,单独定义 def get_cali_count(user): if user.is_authenticated: return Tools_Calibrated.objects.filter(user=user, calibrated=True, issued=True).count() return 0 # 需要用到该变量的视图中调用 def my_view(request): context = { "Calicount": get_cali_count(request.user), # 其他上下文变量 } return render(request, "my_template.html", context)
如果使用类视图,可以通过重写get_context_data方法、或者自定义Mixin复用这段逻辑。
内容的提问来源于stack exchange,提问作者Andre
相关产品推荐
相关产品推荐

