使用 django-allauth 进行 Django 首次登录检测

Django First time Login detection with django-allauth

所以我的代码基于这个问题 Redirect User to another url with django-allauth log in signal 但我仍然遇到一些问题。

基本上我想检测第一次登录,以便我可以使用 django-allauth

强制更改密码

我创建了一个 adapter.py:

class AccountAdapter(DefaultAccountAdapter):

    def get_login_redirect_url(self, request):
        threshold = 90  # seconds

        is_first_time = False
        if request.user.last_login:
            is_first_time = (request.user.last_login - request.user.date_joined).seconds < threshold

        if request.user.last_login is None or is_first_time:
            log.info(
                'The user {request.user} is login in for the first time so '
                'lets set a new password'.format(**locals())
            )
            url = '/accounts/password/change/'
        else:
            log.info(
                'The user {request.user} is NOT login in for the first '
                'time'.format(**locals())
            )
            url = settings.LOGIN_REDIRECT_URL
        return resolve_url(url)

一切似乎都工作正常,除了 1 个案例是我在 django 管理员中创建一个新用户并给他一个临时密码。 然后我尝试使用该用户登录并故意提供错误的初始密码。出于某种原因,似乎 user.last_login 得到了更新(尽管如果我去 django 管理,日期还没有不同)。

当我最终输入正确的初始密码时,我登录了,但随后我的代码失败并输入了他假定该用户之前已经登录的位,因此它不会调用强制密码更改位。

这是我到目前为止调试的结果

    is_first_time:  False
    request.user.last_login:  2015-05-17 18:02:33.424718
    request.user.date_joined:  2015-05-17 18:00:26.191912
    INFO 2015-05-17 18:02:33,431 adapter 2955 139903929153280
    The user pai <pai@example.com> is NOT login in for the first time

有什么想法是错误的吗?这不是普遍问题吗??

我仍然不知道问题出在哪里,但我最终通过在数据库中创建一个布尔字段来告诉我是否已登录来解决这个问题

def check_if_first_time_login(user):
    is_first_time_login = None
    for type in ['administrator', 'agent']:
        try:
            user_type = getattr(user, type)
            is_first_time_login = user_type.is_first_time_login
        except ObjectDoesNotExist:
            pass
        else:
            log.info('The user {user} is an {type}'.format(**locals()))
            user_type.is_first_time_login = False
            user_type.save()

    return is_first_time_login


class AccountAdapter(DefaultAccountAdapter):

    def get_login_redirect_url(self, request):
        user = get_object_or_404(get_user_model(), pk=request.user.id)

        is_first_time_login = check_if_first_time_login(user)

        if is_first_time_login:
            log.info(
                'The user {user} is login in for the first time so '
                'lets set a new password'.format(**locals())
            )
            url = '/accounts/password/change/'
        else:
            log.info(
                'The user {user} is NOT login in for the first '
                'time'.format(**locals())
            )
            url = settings.LOGIN_REDIRECT_URL
        return resolve_url(url)