Django 1.8.2运行报错:AttributeError: 'WSGIRequest'对象无'user'属性
嘿,我来帮你搞定这个问题!你遇到的AttributeError: 'WSGIRequest' object has no attribute 'user'其实是Django 1.8里500错误视图的一个常见坑,咱们一步步拆解:
问题根源
你的报错出现在自定义的render函数里,当它尝试访问request.user.is_authenticated()时失败——而这个render是被500错误处理视图server_error调用的。
Django的机制是:当发生未捕获的异常触发500错误时,会直接调用错误处理视图,不会完整执行所有中间件。负责给request对象附加user属性的AuthenticationMiddleware正好属于被跳过的中间件之一,所以此时的request根本没有user这个属性。
看你的中间件配置是没问题的(AuthenticationMiddleware在SessionMiddleware之后,顺序正确),但架不住500错误不走这条流程呀!
解决方案
这里有几个靠谱的修复方式,你选一个适合你的:
1. 在500错误视图里手动补全user属性
直接在server_error函数里给request添加上user属性,用匿名用户兜底:
from django.contrib.auth.models import AnonymousUser def server_error(request): # 手动添加user属性,避免render函数报错 if not hasattr(request, 'user'): request.user = AnonymousUser() res = render(request, 'home/500.html') res.status_code = 500 return res
2. 给自定义render函数加防御性检查
修改你的render函数,先判断request是否有user属性,再做后续操作:
def render(request, template_name, dictionary=None): """ :param request: Django request object :param template_name: template name :param dictionary: parameter of dictionary """ dictionary = dictionary or {} dictionary.update({ 'settings': settings, 'DEBUG': settings.DEBUG, 'server_time': int(time.time()), }) # 先检查request是否包含user属性,再判断是否已认证 if hasattr(request, 'user') and request.user.is_authenticated(): dictionary['user_hashid'] = hashid.encode(request.user.id) temp = template_name.replace('.html', '').split('/') if len(temp) == 1: module = 'v{name}'.format(name=temp[0].capitalize()) else: name = ''.join([t.capitalize() for t in temp]) module = 'v{name}'.format(name=name) dictionary['load_module'] = module return django_render( request, template_name, dictionary )
3. (可选)自定义错误处理中间件(进阶)
如果你的项目里有很多错误视图都需要处理这个问题,可以写一个中间件,确保在错误处理时也能加载user属性,但这个方法相对复杂一些,前面两个方案已经足够解决你的问题了。
验证一下
不管选哪个方案,之后再触发500错误时,render函数就能正常判断用户状态,不会再抛出这个AttributeError啦。
内容的提问来源于stack exchange,提问作者Zhiyuan Leng

