Django,如何用名字和姓氏验证用户?

1 投票
4 回答
1924 浏览
提问于 2025-04-15 21:40

我想用名字和姓氏来验证用户。

这是我正在使用的代码:

user = auth.authenticate(first_name=firstname, last_name=lastname, password=password)

但是它总是返回 NoneType: None。

我检查过名字、姓氏和密码,似乎都是正确的。

我到底哪里出错了呢?谢谢!

4 个回答

2

这是在@T. Stone的想法基础上发展出来的。为什么不让用户用他们的名字和姓氏注册,然后把这两个名字连在一起,作为他们的用户名呢?每次用户登录时,你只需要把这两个字段再组合一下,使用这个字符串。

虽然这样做可能无法使用一些自动生成的表单,但这并不是什么大问题。我只会把这两个字符串合并成一个,把字母都变成小写,然后用这个作为用户名,每次登录的时候也这样做。

2

你可以在后台认证功能中使用任何参数,也就是说:

class FirstLastNameBackend(object):
  def authenticate(self, first_name=None, last_name=None, password=None):
    pass #your user auth code goes here

为了验证用户,你需要调用

user = auth.authenticate(first_name=firstname,
    last_name=lastname,
    password=password)

不过有一个缺点,就是你需要自己实现登录表单,而且这个认证在管理界面是不能用的。

3

这里的难点在于,通常你会通过创建一个自定义的认证后端来处理这个问题,这个后端需要实现 authenticateget_user 这两个功能。不过,authenticate 函数的参数格式是:

def authenticate(self, username=None, password=None):

在Django中,任何调用这个函数的地方只会传入两个参数:用户名和密码。这就意味着,如果用其他方式实现,就会导致使用任何通用的认证表单和管理界面时出现问题。

我能想到的唯一解决办法,虽然有点不太靠谱,就是把用户名作为一个字符串输入,比如“First Last”(用空格分隔),然后再把它拆分开来使用...

(这都是未经测试的,但你明白我的意思)

class FirstLastNameBackend(object):
    def authenticate(self, username=None, password=None):
        first, last = username.split(' ', 1)
        try:
            user = User.objects.get(first_name=first, last_name=last)
            if user:
                # Check if the password is correct
                # check if the user is active
                # etc., etc.
                return user
        except:
            pass
        return None

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

Django的文档提供了很多关于如何做自定义后端的有用信息: 使用自定义后端进行用户认证

另外要注意的是,有些姓氏中间有空格,比如“de la Cruz”。如果在 split 函数中把 maxsplit 设置为1,就可以避免这个问题。

撰写回答