当用户更改密码时,我想发送一个信号,以便我可以在某些型号上做一些事情。
如何创建此信号?
我查看了用户的post_save
信号:
post_save.connect(user_updated, sender=User)
但是,我似乎没有任何东西可以检查密码是否已更改:
def user_updated(sender, **kwargs):
print(kwargs) # {'created': False, 'raw': False, 'instance': <User: 100002>, 'update_fields': None, 'signal': <django.db.models.signals.ModelSignal object at 0x7ff8862f03c8>, 'using': 'default'}
我也看到有password_change_done
身份验证视图,但我不确定我是如何使用它的。 https://docs.djangoproject.com/en/1.10/topics/auth/default/#built-in-auth-views
有什么想法吗?
答案 0 :(得分:5)
您可以使用pre_save信号。 kwargs['instance']
将包含
更新密码,您可以使用User.objects.get(id=
user.id).password
@receiver(pre_save, sender=User)
def user_updated(sender, **kwargs):
user = kwargs.get('instance', None)
if user:
new_password = user.password
try:
old_password = User.objects.get(pk=user.pk).password
except User.DoesNotExist:
old_password = None
if new_password != old_password:
# do what you need here
答案 1 :(得分:3)
如果您使用的是自定义用户模型,则可能会与set_password()
调用相交以在实例上设置标记,然后在信号中选择其存在:
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db.models.signals import post_save
class User(AbstractBaseUser, PermissionsMixin):
def set_password(self, password):
super(User, self).set_password(password)
self._set_password = True
@classmethod
def user_saved(cls, sender, instance, **kwargs):
if getattr(instance, '_set_password', False):
# Take action
post_save.connect(User.user_saved, sender=User)
答案 2 :(得分:0)
我找到了一个解决方案,这样您就不必比较密码哈希值,即使密码相同,哈希值也可能不同。
@receiver(pre_save, sender=get_user_model())
def detect_password_change(sender, instance, **kwargs):
"""
Checks if the user changed his password
"""
if instance._password is None:
return
try:
user = get_user_model().objects.get(id=instance.id)
except get_user_model().DoesNotExist:
return
print("password changed")
# if you get here, the user changed his password