访问Django编辑资料页报错:'AnonymousUser' object has no attribute '_meta'
问题排查:'AnonymousUser' object has no attribute '_meta' 错误
错误原因分析
你访问http://127.0.0.1:8000/account/profile/edit/时触发的这个错误,核心问题是未登录的匿名用户(AnonymousUser)尝试访问需要登录权限的编辑页面。
Django的AnonymousUser是一个特殊的占位对象,它并不继承自常规的User模型,自然也就没有_meta属性——而你的EditProfileForm是基于User模型构建的,当你把instance=request.user传给表单时,如果用户未登录,request.user就是AnonymousUser,表单尝试读取它的模型元信息时就会直接报错,这就是报错指向/usr/local/lib/python2.7/dist-packages/django/utils/functional.py第205行的原因。
解决办法
你需要给所有涉及用户个人信息的视图添加登录校验,确保只有已登录用户才能进入这些页面,这里有两种常用的实现方式:
方式1:使用Django官方推荐的login_required装饰器
这是最简洁高效的方案,先在views.py中导入装饰器,再给目标视图添加装饰器即可:
首先导入装饰器:
from django.contrib.auth.decorators import login_required
然后给需要校验的视图加上装饰器:
@login_required def view_profile(request): args = {'user' : request.user} return render(request,'accounts/profile.html',args) @login_required def edit_profile(request): if request.method=="POST": form = EditProfileForm(request.POST,instance=request.user) if form.is_valid(): form.save() return redirect('/account/profile') else: form = EditProfileForm(instance=request.user) args = {'form' : form} return render(request,'accounts/edit_profile.html',args) @login_required def change_password(request): if request.method == "POST": form = PasswordChangeForm(data=request.POST,user=request.user) if form.is_valid(): form.save() update_session_auth_hash(request, form.user) return redirect('/account/profile') else: return HttpResponse("password doest not match,go back and try again") else: form = PasswordChangeForm(user=request.user) args = {'form' : form} return render(request,'accounts/change_password.html',args)
配置完成后,未登录用户访问这些页面时,Django会自动跳转到你配置的登录页面/account/login/,用户登录成功后会自动跳转到原本想要访问的页面。
方式2:在视图内部手动校验登录状态
如果你不想使用装饰器,也可以在视图函数开头添加登录判断逻辑:
def edit_profile(request): # Django 1.x版本用request.user.is_authenticated(),Django 2+版本用request.user.is_authenticated if not request.user.is_authenticated(): return redirect('/account/login/') # 后续的视图逻辑保持不变
不过更推荐使用login_required装饰器,它是Django官方的最佳实践,代码更简洁易维护。
额外优化建议
- 你当前的跳转逻辑用了硬编码URL(比如
redirect('/account/profile')),建议换成Django的反向解析功能,比如redirect('view_profile'),这样后续修改URL配置时不用手动修改视图里的跳转路径。 - 错误提示用
HttpResponse直接返回文本的体验较差,可以换成渲染错误提示模板,或者使用Django的消息框架来展示错误信息。
内容的提问来源于stack exchange,提问作者Jay Suthar
相关产品推荐
相关产品推荐

