Django 'AnonymousUser' object has no attribute '_meta'
Question:
I am using social login in my Django app. So, I have added additional backends in my settings.py
file.
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',
]
I have also used UserCreationForm
for signup,
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' )
This is the views file,
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})
Now, I get this error when i click signup button on my form,
'AnonymousUser' object has no attribute '_meta'
at the line,
login(request,user,backend='django.contrib.auth.backends.ModelBackend')
Why so ?
I can see in my admin panel that user has been saved.
What is causing this error ? and how to solve it ?
EDIT –
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'
Answers:
You already have the user when you save the form, so you don’t need to call authenticate
since you already provide the backend when calling login()
:
user = form.save()
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
Came here looking for this error. Our stack is django-oscar + wagtail. It turns out we removed oscar.apps.customer.auth_backends.EmailBackend
from our AUTHENTICATION_BACKENDS
. Putting it back solved the issue.
The UserCreationForm() provides for both password and the password_confirmation fields.
Authentication fails in this case because you are trying to get “password” which does not exists, therefore returning user as None.
If you print form.cleaned_data, you get a dictionary similar to this
{'username': 'myuser', 'password1': 'pass1234', 'password2': 'pass1234'}
Changing the raw_pass line should fix the issue:
raw_pass = form.cleaned_data.get('password1')
Cause of Returning None While logging with created user from registration form , in DB it is checking specific user with encrypted password ,but we are saving password in text from that is why if you give even correct username and password ,it is failing
Add below model backends in setting.py file
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
or pass backend to login function itself
login(request, username,password, backend='django.contrib.auth.backends.ModelBackend')
import make_password function and pass password to it which is comming from registration form then it will save password into Db in encrypted form
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
I believe it’s because you havent hashed the password. This worked for me. Try:
user = userform.save()
user.set_password(user.password)
user.save()
Ran into the same issue (using Django 2.2).
To fix I added AUTH_USER_MODEL = 'myapp.MyUser'
to settings.py above MIDDLEWARE
.
From the 2.2 Docs on substituting a custom User model:
" Django allows you to override the default user model by providing a value for the AUTH_USER_MODEL setting that references a custom model: AUTH_USER_MODEL = 'myapp.MyUser'
. This dotted pair describes the name of the Django app (which must be in your INSTALLED_APPS), and the name of the Django model that you wish to use as your user model "
I was running into the same problem because I had customized authentication and was passing wrong arguments in authenticate()
You did not share your custom user model, but it could be that you are using email as the USERNAME_FIELD
.
class User(AbstractUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
So in the relevant view, you will need to pass email (and not username) as an argument to 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)
...
I am using social login in my Django app. So, I have added additional backends in my settings.py
file.
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',
]
I have also used UserCreationForm
for signup,
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' )
This is the views file,
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})
Now, I get this error when i click signup button on my form,
'AnonymousUser' object has no attribute '_meta'
at the line,
login(request,user,backend='django.contrib.auth.backends.ModelBackend')
Why so ?
I can see in my admin panel that user has been saved.
What is causing this error ? and how to solve it ?
EDIT –
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'
You already have the user when you save the form, so you don’t need to call authenticate
since you already provide the backend when calling login()
:
user = form.save()
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
Came here looking for this error. Our stack is django-oscar + wagtail. It turns out we removed oscar.apps.customer.auth_backends.EmailBackend
from our AUTHENTICATION_BACKENDS
. Putting it back solved the issue.
The UserCreationForm() provides for both password and the password_confirmation fields.
Authentication fails in this case because you are trying to get “password” which does not exists, therefore returning user as None.
If you print form.cleaned_data, you get a dictionary similar to this
{'username': 'myuser', 'password1': 'pass1234', 'password2': 'pass1234'}
Changing the raw_pass line should fix the issue:
raw_pass = form.cleaned_data.get('password1')
Cause of Returning None While logging with created user from registration form , in DB it is checking specific user with encrypted password ,but we are saving password in text from that is why if you give even correct username and password ,it is failing
Add below model backends in setting.py file
AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',)
or pass backend to login function itself
login(request, username,password, backend='django.contrib.auth.backends.ModelBackend')
import make_password function and pass password to it which is comming from registration form then it will save password into Db in encrypted form
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
I believe it’s because you havent hashed the password. This worked for me. Try:
user = userform.save()
user.set_password(user.password)
user.save()
Ran into the same issue (using Django 2.2).
To fix I added AUTH_USER_MODEL = 'myapp.MyUser'
to settings.py above MIDDLEWARE
.
From the 2.2 Docs on substituting a custom User model:
" Django allows you to override the default user model by providing a value for the AUTH_USER_MODEL setting that references a custom model: AUTH_USER_MODEL = 'myapp.MyUser'
. This dotted pair describes the name of the Django app (which must be in your INSTALLED_APPS), and the name of the Django model that you wish to use as your user model "
I was running into the same problem because I had customized authentication and was passing wrong arguments in authenticate()
You did not share your custom user model, but it could be that you are using email as the USERNAME_FIELD
.
class User(AbstractUser):
email = models.EmailField(unique=True)
USERNAME_FIELD = 'email'
So in the relevant view, you will need to pass email (and not username) as an argument to 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)
...