Django如何覆盖update_last_login,它是成功登录后的信号接收者

问题描述 投票:0回答:1

我正在定义自定义用户,我需要覆盖update_last_login中定义的.venv/lib/python3.7/site-packages/django/contrib/auth/models.py

如下所示:

def update_last_login(sender, user, **kwargs):
    """
    A signal receiver which updates the last_login date for
    the user logging in.
    """
    user.last_login = timezone.now()
    user.save(update_fields=['last_login'])

并且在发送信号的.venv/lib/python3.7/site-packages/django/contrib/auth/__init__.py

from .signals import user_logged_in

....


def login(request, user, backend=None):

    ...

    user_logged_in.send(sender=user.__class__, request=request, user=user)

所以如何在我的custom_user中覆盖update_last_login。

django
1个回答
0
投票

在此示例中,我考虑到您已经放置了一个名为users的应用中的模型,视图和信号-您可以根据自己的特定需求对其进行调整。

如果您有一个名为users的django应用程序,并且您的应用程序树为:

users+
     |
     +__init__.py
     |
     +signals.py
     |
     +models.py
     |
     +views.py

再创建一个文件callbacks.py,将是

users+
     |
     +__init__.py
     |
     +signals.py
     |
     +models.py
     |
     +views.py
     |
     +callbacks.py

在您的callbacks.py中添加必要的导入并添加自定义信号的处理程序:

from django.dispatch import receiver
from users.signals import user_logged_in

@receiver(user_logged_in, sender=User)
def update_last_login(sender, user, **kwargs):
    """
    A signal receiver which updates the last_login date for
    the user logging in.
    """
    user.last_login = timezone.now()
    user.save(update_fields=['last_login'])

注意,装饰器已添加-这是使回调成为信号接收器所必需的。根据需要调整信号处理程序中的逻辑。

现在,在您的views.py顶部添加

from users.callback import update_last_login
from users.signals import user_logged_in

views.py的最底部,将信号连接到其处理程序:

update_last_login.connect(update_last_login)

如果要发送和正确处理信号,这是必不可少的

注意:在这里,我假设您对实际视图使用views.py并拥有它喜欢

def login(request, user, backend=None):

    ...
    # Sending the actual signal
    user_logged_in.send(sender=user.__class__, request=request, user=user)

请进行所有必要的调整,以匹配项目的布局。

如果使用原始信号,而不是自定义信号:

from django.contrib.auth.signals import user_logged_in

然后您甚至不需要发送信号-只要您提供处理程序,并将其连接到views.py并完成所有操作,信号就会自动为您触发处理程序中保存用户数据的必要步骤。如果需要,您仍然可以手动发送它以触发其他执行。

要创建您的自定义信号,请在您的[[signals.py中添加类似内容

from django.dispatch import Signal custom_login_signal = Signal(providing_args=["user"])
然后,在[[callbacks.py
中,使用此信号代替原始信号:

from django.dispatch import receiver from users.signals import custom_login_signal @receiver(custom_login_signal, sender=User) def update_last_login(sender, user, **kwargs): """ A signal receiver which updates the last_login date for the user logging in. """ user.last_login = timezone.now() user.save(update_fields=['last_login']) 然后,在您的

* views.py
中,将信号导入并像以前一样将其连接到处理程序,但是这次在您的视图中发送信号:

def custom_login(request, user, backend=None): ... custom_login_signal.send(sender=user.__class__, request=request, user=user) 当然,这假定您将新定义的信号连接到处理程序从

callbacks.py
导入。在

views.py的最底部,添加:

custom_login_signal.connect(update_last_login)
© www.soinside.com 2019 - 2024. All rights reserved.