我们有一个Django项目,每当她打电话给我们时,都会为一个人创建一个用户帐户。此人可能会或可能不会在以后使用她的帐户登录我们的网站。
问题:如何确定用户曾登录我们的网站?
澄清:我想回答上面几百个现有用户的问题,而不仅仅是针对此时创建的新用户。
思考1:检查User.last_login
。不幸的是,无论是否登录,Django都会在创建用户时将last_login
初始化为datetime.datetime.now()
。
思考2:检查User.last_login
是否与User.date_joined
匹配。不幸的是,Django将这两个这些字段初始化为datetime.now()
,它们相隔几微秒:
In [1]: u = User.objects.create(username="bla")
In [2]: u.date_joined - u.last_login
Out[2]: datetime.timedelta(0, 0, 23)
我正在使用的当前黑客:假设用户至少登录了一次 iff user.last_login - user.date_joined >= datetime.timedelta(seconds=1)
。
有没有更好的方法来判断用户是否曾登录过?
答案 0 :(得分:3)
如果是较新版本的Django(> 1.8),则应使用User.last_login。这就是documentation陈述的内容:
LAST_LOGIN
用户上次登录的日期时间。
在Django 1.8中更改:如果用户从未使用过,则此字段将为null 登录。以前默认设置为当前日期/时间。
答案 1 :(得分:2)
当你说date_joined
和last_login
都设置为创建时的当前日期时,我会认为你是对的,并且由于某种原因,已经有足够的时间过去了在两个任务之间创建一个明显的增量。
如果是这种情况,那么您可以接受@ LAK的建议并创建pre_save(并检查实例的ID是否为0)或post_save(并检查created
参数并手动将last_login
字段设置为None
或与date_joined
相同的值。从那里你所有的未来数据都保存在你似乎鄙视的一秒钟模糊之中。
至于你现有的数据,我认为你很难用你所获得的数据做出最好的猜测。我认为假设你正在制造它并不太冒险。如果要将其清理为与所有新数据相同,则只需更新数据库即可设置last_login
值。如果您使用South,这很容易与数据迁移相关。否则,您可以在部署新代码更改后创建要运行的脚本。
老实说,我不认为这是一个问题,他们有点失望。只要您假设用户很可能无法在创建帐户的时间范围内登录,那么似乎没有理由添加一些额外的工作来强制它完全匹配。
答案 2 :(得分:0)
我会使用F
对象将last_login
与date_joined
进行比较。如果它们相等,那么用户从未登录过(或者至少在他们初次注册后从未登录过,这是您可以确定的最佳状态)
from django.db.models import F
User.objects.filter(last_login=F('date_joined'))
<强>更新强>
嗯,它在我的环境中成功运行,但我认为可能这两个可能会在几微秒或更长时间内关闭。如果是这种情况,那么我认为您唯一的办法是实际手动检查每个User
。如果您需要更高的准确性,您可以对以下内容进行修改,但通常情况下,我认为在最初创建计数之后从未登录的用户可能被计为“从未登录”用于所有意图和目的 - 方式,他们已经放弃了帐户。
if user.date_joined.date() == user.last_login.date():
# do something
如果您需要更高的准确度:
date_joined = datetime.combine(user.date_joined.date(), time(user.date_joined.hour, user.date_joined.minute))
last_login = datetime.combine(user.last_login.date(), time(user.last_login.hour, user.last_login.minute))
if date_joined == last_login:
# do something
这实际上创建了新的日期时间对象,消除了秒和微秒的差异。当然,1分钟的准确度水平已经足够了。
答案 3 :(得分:0)
此解决方案可以过滤已登录或未登录网站的用户QuerySet
。
filter_user_has_used_site()
和filter_user_hasnt_used_site()
函数适用于包含QuerySet
的{{1}}。
auth.User
和filter_resource_has_used_site()
适用于任何查询集,哪个模型的filter_resource_hasnt_used_site()
字段为ForeignKey
到user
。
它仅适用于mysql,但可以很容易地支持其他数据库引擎。
auth.User