Django - 身份验证不会向用户添加后端
Django - Authenticate doesn't add backend to user
我创建了一个注册表单,尽管成功创建了一个用户但无法登录,因为 authenticate
无法分配后端,即使用户随后被标记为 is_authenticated=True
我使用身份验证的方式有什么不正确的地方吗?
(请注意我使用的是 django all_auth 但不确定这是否对这里有影响?)
在 login() 时它产生了这个错误:
ValueError:You have multiple authentication backends configured and therefore must provide the backend argument or set the backend attribute on the user.
查看:
....
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)
个人资料表格:
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
当您调用 authenticate
时,如果身份验证成功,它将 return 一个用户。调用 login
时应使用此用户。
user = authenticate(request, username=form.cleaned_data['email'],
password=form.cleaned_data['password1'])
login(request, user)
请注意,除非您有自定义身份验证后端,否则您应该传递 username
而不是 user
。
在 Django 1.10+ 中,如果您已经拥有用户实例,则不必调用 authenticate
。当您调用 login
时,您可以提供后端作为参数,例如:
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
有关详细信息,请参阅 selecting the authentication backend 上的文档。
您将在 "settings.py" 中设置多个身份验证后端,如下所示:
# "settings.py"
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
# ...,
# ...,
]
这种情况下,需要在中设置backend='django.contrib.auth.backends.ModelBackend'为"login()" =]"views.py" 如下图那么错误就解决了:
# "views.py"
....
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, backend='django.contrib.auth.backends.ModelBackend')
# ↑ ↑ ↑ Here ↑ ↑ ↑
我创建了一个注册表单,尽管成功创建了一个用户但无法登录,因为 authenticate
无法分配后端,即使用户随后被标记为 is_authenticated=True
我使用身份验证的方式有什么不正确的地方吗?
(请注意我使用的是 django all_auth 但不确定这是否对这里有影响?)
在 login() 时它产生了这个错误:
ValueError:You have multiple authentication backends configured and therefore must provide the backend argument or set the backend attribute on the user.
查看:
....
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)
个人资料表格:
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
当您调用 authenticate
时,如果身份验证成功,它将 return 一个用户。调用 login
时应使用此用户。
user = authenticate(request, username=form.cleaned_data['email'],
password=form.cleaned_data['password1'])
login(request, user)
请注意,除非您有自定义身份验证后端,否则您应该传递 username
而不是 user
。
在 Django 1.10+ 中,如果您已经拥有用户实例,则不必调用 authenticate
。当您调用 login
时,您可以提供后端作为参数,例如:
login(request, user, backend='django.contrib.auth.backends.ModelBackend')
有关详细信息,请参阅 selecting the authentication backend 上的文档。
您将在 "settings.py" 中设置多个身份验证后端,如下所示:
# "settings.py"
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
# ...,
# ...,
]
这种情况下,需要在中设置backend='django.contrib.auth.backends.ModelBackend'为"login()" =]"views.py" 如下图那么错误就解决了:
# "views.py"
....
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, backend='django.contrib.auth.backends.ModelBackend')
# ↑ ↑ ↑ Here ↑ ↑ ↑