Django“AnonymousUser”对象没有“_meta”属性。

30

我在我的Django应用中使用社交登录。因此,我在settings.py 文件中添加了额外的后端。

AUTHENTICATION_BACKENDS = [
    'django.contrib.auth.backends.ModelBackend',
    'social_core.backends.open_id.OpenIdAuth',
    'social_core.backends.google.GoogleOpenId',
    'social_core.backends.google.GoogleOAuth2',
    'social_core.backends.google.GoogleOAuth',
    'social_core.backends.twitter.TwitterOAuth',
    'social_core.backends.facebook.FacebookOAuth2',
    'social_core.backends.github.GithubOAuth2',

我也使用了UserCreationForm来进行注册。

class SignupForm(UserCreationForm):
    first_name = forms.CharField(max_length=30, required=True, help_text='Required.')
    last_name = forms.CharField(max_length=30, required=True, help_text='Required.')
    email = forms.EmailField(max_length=254, help_text='Required. Inform a valid email address.')

    class Meta:
        model = User
        fields = ('username', 'first_name', 'last_name', 'email', 'password1', 'password2' )

这是视图文件。

def signup(request):
    if request.method == 'POST':
        form  = SignupForm(request.POST)
        if form.is_valid():
            form.save()
            username = form.cleaned_data.get('username')
            raw_pass = form.cleaned_data.get('password')
            user = authenticate(request, username=username, password=raw_pass)
            login(request,user,backend='django.contrib.auth.backends.ModelBackend')
            url = reverse('location:get_location')
            print("location_url ", url)
            return HttpResponseRedirect(url)
    else:
        form = SignupForm()
    return render(request, 'signup.html', {'form':form})

当我在表单上点击注册按钮时,出现了这个错误:

'AnonymousUser' object has no attribute '_meta'
login(request,user,backend='django.contrib.auth.backends.ModelBackend')

为什么会这样?

我可以在我的管理面板中看到用户已被保存。

是什么导致了这个错误?怎样解决它?

编辑 -

Internal Server Error: /signup/
Traceback (most recent call last):
  File "/home/luvpreet/Envs/weather/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/home/luvpreet/Envs/weather/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
   File "/home/luvpreet/Envs/weather/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/luvpreet/Desktop/drf-vogo/weather/weather/pilot/views.py", line 45, in signup
    login(request,user,backend='django.contrib.auth.backends.ModelBackend')
  File "/home/luvpreet/Envs/weather/local/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 154, in login
     request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
  File "/home/luvpreet/Envs/weather/local/lib/python2.7/site-packages/django/utils/functional.py", line 239, in inner
    return func(self._wrapped, *args)
AttributeError: 'AnonymousUser' object has no attribute '_meta'

@Alasdair请检查堆栈跟踪,from django.contrib.auth import login, authenticate - Luv33preet
7个回答

44

当您保存表单时,已经拥有了用户,因此在调用login()时,不需要调用authenticate,因为您已经提供了后端:

user = form.save()
login(request, user, backend='django.contrib.auth.backends.ModelBackend')

3

我来到这里是为了寻找这个错误。我们的堆栈是django-oscar + wagtail。结果发现我们从AUTHENTICATION_BACKENDS中删除了oscar.apps.customer.auth_backends.EmailBackend。将其放回去解决了问题。


2

我认为这是因为您没有对密码进行哈希处理。以下方法适用于我。请尝试:

        user = userform.save()
        user.set_password(user.password)
        user.save()

1

当使用注册表单创建用户进行登录时,返回None的原因是,在数据库中它正在检查具有加密密码的特定用户,但我们将密码保存为文本形式,因此即使您提供正确的用户名和密码,它也会失败。

在setting.py文件中添加以下模型后端

AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)

或者将后端传递给登录函数本身

login(request, username,password, backend='django.contrib.auth.backends.ModelBackend')

导入make_password函数并将来自注册表单的密码传递给它,然后它将以加密形式保存密码到数据库中

from django.contrib.auth.hashers import make_password

raw_pass = form.cleaned_data.get('password') raw_pass = make_password(form.cleaned_data.get('password'))

Django=2.2.4


1

UserCreationForm()提供了密码和密码确认字段。在此情况下,身份验证失败,因为您正在尝试获取不存在的“密码”,因此将用户返回为None。如果打印form.cleaned_data,您会得到一个类似于这个字典:

{'username': 'myuser', 'password1': 'pass1234', 'password2': 'pass1234'}

更改raw_pass行应该可以解决问题:

raw_pass = form.cleaned_data.get('password1')


1
遇到了相同的问题(使用Django 2.2)。
为了解决这个问题,我在settings.py中添加了在之前。
2.2文档中替换自定义用户模型:
“ Django允许您通过提供引用自定义模型的AUTH_USER_MODEL设置的值来覆盖默认用户模型:AUTH_USER_MODEL ='myapp.MyUser'。这个点对描述了Django应用程序的名称(必须在INSTALLED_APPS中),以及您希望用作用户模型的Django模型的名称。”

0

我遇到了同样的问题,因为我定制了身份验证并在authenticate()中传递了错误的参数。

您没有分享您的自定义用户模型,但可能是因为您正在使用电子邮件作为USERNAME_FIELD

class User(AbstractUser):
    email = models.EmailField(unique=True)
    USERNAME_FIELD = 'email'

所以在相关的视图中,您需要将电子邮件(而不是用户名)作为参数传递给authenticate()函数。
    if form.is_valid():
        form.save()
        email = form.cleaned_data['email']
        password = form.cleaned_data['password1']
        user = authenticate(request, email=email, password=password)
        login(request, user)
    ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接