前面我们讲过Django自定义用户模型并集成阿里云短信 但这种登录时通过用户名和密码登录

from django.views import View
from django.contrib.auth import authenticate, login

class LoginView(View):
    def post(self, request):
        username = request.POST.get("username", "")
        password = request.POST.get("password", "")

        user = authenticate(username=username, password=password)  #用户验证
        if user:
            login(request, user)  #用户登录
            return render(request, "index.html")
        else:
            return render(request, "login.html")

这里我们通过用户名与密码进行验证,但是有时我们想要通过邮箱与密码进行验证,此时通过这种方法是不行的,我们需要重写authenticate()方法。方法如下:

在setting.py中进行配置

AUTHENTICATION_BACKENDS = (
'user.views.CustomBackend',
)

使用的认证后台通过AUTHENTICATION_BACKENDS 设置指定。它应该是一个包含Python 路径名称的元组,它们指向的Python 类知道如何进行验证。这些类可以位于Python 路径上任何地方。

在views.py中重新定制authenticate()方法

from django.contrib.auth import authenticate, login
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q

from users.models import UserProfile


class CustomBackend(ModelBackend):
        def authenticate(self, request, username=None, password=None, **kwargs):
        """判断用户名(手机号码)和密码是否正确"""
        query_set = User.objects.filter(Q(username=username) | Q(telephone=username))
        try:
            if query_set.exists():
                user = query_set.get()
                if user.check_password(password):
                    return user
        except:
            return None
        return None

不管怎样, authenticate 至少应该检查凭证, 如果凭证合法,它应该返回一个匹配于登录信息的 User 实例。如果不合法,则返回 None.

这里通过Q()方法实现查询输入的username是否是email,关于Q()方法,可以见我之前的博客 Django基础-查询操作 因为在django中用户的密码存储在数据库中是经过加密的,如果直接用password==password来进行验证是不对的。通过user.check_password(password)方法来进行验证密码是否正确。

这样便重新写了authenticate方法。可以通过用户名或者邮箱直接登录了。

最后修改:2020年7月28日 10:23