在 django 项目中允许电子邮件和用户名登录

Dan*_*ang 2 python django

我正在为一所学校创建一个 django 项目,主要有三种用户 - 家长、老师和学生。对于家长和老师,我希望他们使用电子邮件登录(他们目前使用电子邮件登录旧系统)。

但是,对于学生,我希望他们使用传统的用户名方法登录(因为年幼的孩子没有电子邮件)。这可以在 Django 中进行还是只允许一种用户身份验证模型?

Kam*_*mil 6

您可以创建单独的AuthenticationEmailBackend仅用于通过电子邮件登录并将其添加到AUTHENTICATION_BACKENDS设置中。通过这种方式AUTHENTICATION_BACKENDS,如果以前的身份验证失败,则使用different作为替代方案AUTHENTICATION_BACKENDS

应用程序/auth.py

from django.contrib.auth import get_user_model
from django.contrib.auth.models import User


class AuthenticationEmailBackend(object):
    def authenticate(self, username=None, password=None, **kwargs):
        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(email=username)
        except UserModel.DoesNotExist:
            return None
        else:
            if getattr(user, 'is_active', False) and user.check_password(password):
                return user
        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
Run Code Online (Sandbox Code Playgroud)

设置.py

AUTHENTICATION_BACKENDS = (
    "django.contrib.auth.backends.ModelBackend",
    ...
    "app.auth.AuthenticationEmailBackend",
)
Run Code Online (Sandbox Code Playgroud)

如果您django.contrib.auth.backends.ModelBackend在列表中保留默认值,用户可以通过用户名或电子邮件登录。


gil*_*gil 5

从 Django 1.11 开始,authenticate 方法似乎需要请求参数:

def authenticate(self, request, username=None, password=None)
Run Code Online (Sandbox Code Playgroud)

根据Django 文档中的说法。