如何断开update_last_login?
How to disconnect update_last_login?
我在 Django 中从头开始实现了自己的 User
class。但是当我登录时出现此错误:
The following fields do not exist in this model or are m2m fields: last_login
我真的不想要字段last_login
。
我做了一些研究,问题就在这里:contrib.aut.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'])
user_logged_in.connect(update_last_login)
我找到了一个解决方法,但它不是一个优雅的解决方案。我在我的 models.py
文件中添加了 user_logged_in.disconnect(update_last_login)
,其中定义了我的 User
class。
有没有更好的解决方案?
目前在 Django 1.7 中...
我认为您定义的解决方法是目前使用 Django 身份验证 login()
方法时唯一有效的解决方案(除了猴子补丁)。我只是假设您使用的是引发此异常的标准 login()
方法。
如果我们看一下 the source for the login method,我们会在方法的末尾找到执行 user_logged_in.send(sender=user.__class__, request=request, user=user)
的调用。正如您所指出的,除了断开连接之外,我们无法阻止此信号的执行。
或者,我们可以猴子修补 login()
方法以删除该信号调用。
from django.contrib.auth import login
def monkey_patch_login(request, user):
"""
Persist a user id and a backend in the request. This way a user doesn't
have to reauthenticate on every request. Note that data set during
the anonymous session is retained when the user logs in.
"""
session_auth_hash = ''
if user is None:
user = request.user
if hasattr(user, 'get_session_auth_hash'):
session_auth_hash = user.get_session_auth_hash()
if SESSION_KEY in request.session:
if _get_user_session_key(request) != user.pk or (
session_auth_hash and
request.session.get(HASH_SESSION_KEY) != session_auth_hash):
# To avoid reusing another user's session, create a new, empty
# session if the existing session corresponds to a different
# authenticated user.
request.session.flush()
else:
request.session.cycle_key()
request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = user.backend
request.session[HASH_SESSION_KEY] = session_auth_hash
if hasattr(request, 'user'):
request.user = user
rotate_token(request)
login = monkey_patch_login
我们会将猴子补丁代码放在需要调用login()
方法的文件的顶部。
不确定这是否与较新版本的 django 或什么有关,但就我而言
user_logged_in.disconnect(update_last_login)
没用。这对我有用(django 2.1):
user_logged_in.disconnect(update_last_login, dispatch_uid='update_last_login')
我在 Django 中从头开始实现了自己的 User
class。但是当我登录时出现此错误:
The following fields do not exist in this model or are m2m fields:
last_login
我真的不想要字段last_login
。
我做了一些研究,问题就在这里:contrib.aut.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'])
user_logged_in.connect(update_last_login)
我找到了一个解决方法,但它不是一个优雅的解决方案。我在我的 models.py
文件中添加了 user_logged_in.disconnect(update_last_login)
,其中定义了我的 User
class。
有没有更好的解决方案?
目前在 Django 1.7 中...
我认为您定义的解决方法是目前使用 Django 身份验证 login()
方法时唯一有效的解决方案(除了猴子补丁)。我只是假设您使用的是引发此异常的标准 login()
方法。
如果我们看一下 the source for the login method,我们会在方法的末尾找到执行 user_logged_in.send(sender=user.__class__, request=request, user=user)
的调用。正如您所指出的,除了断开连接之外,我们无法阻止此信号的执行。
或者,我们可以猴子修补 login()
方法以删除该信号调用。
from django.contrib.auth import login
def monkey_patch_login(request, user):
"""
Persist a user id and a backend in the request. This way a user doesn't
have to reauthenticate on every request. Note that data set during
the anonymous session is retained when the user logs in.
"""
session_auth_hash = ''
if user is None:
user = request.user
if hasattr(user, 'get_session_auth_hash'):
session_auth_hash = user.get_session_auth_hash()
if SESSION_KEY in request.session:
if _get_user_session_key(request) != user.pk or (
session_auth_hash and
request.session.get(HASH_SESSION_KEY) != session_auth_hash):
# To avoid reusing another user's session, create a new, empty
# session if the existing session corresponds to a different
# authenticated user.
request.session.flush()
else:
request.session.cycle_key()
request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = user.backend
request.session[HASH_SESSION_KEY] = session_auth_hash
if hasattr(request, 'user'):
request.user = user
rotate_token(request)
login = monkey_patch_login
我们会将猴子补丁代码放在需要调用login()
方法的文件的顶部。
不确定这是否与较新版本的 django 或什么有关,但就我而言
user_logged_in.disconnect(update_last_login)
没用。这对我有用(django 2.1):
user_logged_in.disconnect(update_last_login, dispatch_uid='update_last_login')