django有能力通过电话或电子邮件登录

时间:2018-01-17 14:08:15

标签: django

我想创建一个django自定义用户模型,以便我可以让我的用户使用手机或电子邮件登录。

这是我提出的解决方案

class ExtendedUser(AbstractBaseUser, PermissionsMixin):
    phonenumber = PhoneNumberField(unique=True, null=True ..)
    email = EmailField(unique=True, null=True ..)
    ...
    USERNAME_FIELD = 'pk'

所以现在登录时,我可以做这样的事情

if cleaned_data['phonenumber']:
   u = User.objects.get(phonenumber=cleaned_data['phonenumber'])
   authenticate(username=u.pk, password=cleaned_data['password'])
   ...

elif cleaned_data['email']:
   ...

我不确定是否可以将USERNAME_FIELD作为pk。 如果不可能,我们可以轻松放置UUIDField。

建议的解决方案是否正常?

2 个答案:

答案 0 :(得分:2)

电子邮件和电话的独特约束是好的。另外,我会设置USERNAME_FIELD ='email'。

然后,我认为您应该尝试创建自定义身份验证后端。您可以查看here

就像Django所说:当有人调用django.contrib.auth.authenticate()时,Django会尝试对其所有身份验证后端进行身份验证。

然后在您的自定义身份验证后端,您可以要求电子邮件或电话:

class CustomAuthenticationBackend:

    def authenticate(self, request, email_or_phone=None, password=None):
        try:
             user = User.objects.get(
                 Q(email=email_or_phone) | Q(phone=email_or_phone)
             )
             pwd_valid = user.check_password(password)
             if pwd_valid:            
                 return user
             return None
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

我认为它可行。让我知道!!

最好的问候。

答案 1 :(得分:0)

django login take two argoman : reqeust and user query so when we get this two things we can login. django authenticate searching in the user model and when user in found ....


def log_in(request):
if request.user.is_authenticated is True:
    return redirect('/home/')
if request.method == 'POST':

    u = request.POST.get('_phone_')
    p = request.POST.get('_pass1_')

    if '@' in u:
        user_check = authenticate(request, email=u, password=p)
    else:
        user_check = MyUser.objects.get(phone= u) # search in our model and find user with phone  


    if user_check is not None:

        user_check.last_login= datetime.now()
        user_check.save(update_fields=['last_login'])

        login(request, user_check)

        return redirect('/home/')

    else:
        return HttpResponse('bad request')
else:
    return render(request, 'login.html')