Issue
I've created a signup form which although successfully creates a user fails to login as authenticate
fails to assign a backend, even though user is then marked as is_authenticated=True
Is there something incorrect in the way that I'm using authenticate?
(note I'm using django all_auth but not sure if that has an impact here?)
At login() it generated this error:
ValueError:You have multiple authentication backends configured and therefore must provide the backend argument or set the backend attribute on the user.
view:
....
form = ProfileForm(request.POST)
if form.is_valid():
user_profile, user = form.save()
authenticate(request, user=form.cleaned_data['email'],
password=form.cleaned_data['password1'])
login(request, user)
models.py
class User(AbstractUser):
def __str__(self):
return self.username
def get_absolute_url(self):
return reverse('users:detail', kwargs={'username': self.username})
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
TITLE_CHOICES = (
.....
)
title = models.CharField(max_length=5, null=True, choices=TITLE_CHOICES)
date_of_birth = models.DateField()
primary_phone = PhoneNumberField()
EMPLOYMENT_CHOICES = (
(....,...)
)
employment_status = models.CharField(max_length=35, choices=EMPLOYMENT_CHOICES)
Profile form:
class ProfileForm(allauthforms.SignupForm):
title = FieldBuilder(UserProfile, 'title', )
first_name = forms.CharField(max_length=30)
last_name = forms.CharField(max_length=30)
date_of_birth = FieldBuilder(UserProfile, 'date_of_birth', widget=SelectDateWidget())
primary_phone = FieldBuilder(UserProfile, 'primary_phone')
employment_status = FieldBuilder(UserProfile, 'employment_status')
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["employment_status"].choices = [("", "---- Select your Employment Status ----"), ] + list(
self.fields["employment_status"].choices)[1:]
def save(self, *args):
data = self.cleaned_data
user = User.objects.create_user(
username=data['email'],
email=data['email'],
password=data['password1'],
first_name=data['first_name'],
last_name=data['last_name'],
)
instance = UserProfile.objects.create(
user=user,
date_of_birth=data['date_of_birth'],
primary_phone=data['primary_phone'],
title=data['title'],
employment_status=data['employment_status'],
)
return instance, user
Solution
When you call authenticate
, it will return a user if the authentication was successful. You should use this user when you call login
.
user = authenticate(request, username=form.cleaned_data['email'],
password=form.cleaned_data['password1'])
login(request, user)
Note that unless you have a custom authentication backend, you should pass username
instead of user
.
In Django 1.10+, you don't have to call authenticate
if you already have the user instance. When you call login
, you can provide the backend as an argument, for example:
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
See the docs on selecting the authentication backend for more info.
Answered By - Alasdair
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.