问题
In template, when I use
{% if topic.creator.is_authenticated %}
Online
{% else %}
Offline
{% endif %}
the users turn out to be always online, even when they has signed out a while ago. So I'm wondering how to check the online users correctly?
回答1:
Thanks this excellent blog post, with slight modifications, I came up with a better solution, which uses memcache, hence less delay per request:
in models.py add:
from django.core.cache import cache
import datetime
from myproject import settings
and add these method the userprofile class:
def last_seen(self):
return cache.get('seen_%s' % self.user.username)
def online(self):
if self.last_seen():
now = datetime.datetime.now()
if now > self.last_seen() + datetime.timedelta(
seconds=settings.USER_ONLINE_TIMEOUT):
return False
else:
return True
else:
return False
in userprofile folder add this middleware.py
import datetime
from django.core.cache import cache
from django.conf import settings
class ActiveUserMiddleware:
def process_request(self, request):
current_user = request.user
if request.user.is_authenticated():
now = datetime.datetime.now()
cache.set('seen_%s' % (current_user.username), now,
settings.USER_LASTSEEN_TIMEOUT)
in settings.py add 'userprofile.middleware.ActiveUserMiddleware',
to MIDDLEWARE_CLASSES
and also add:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}
# Number of seconds of inactivity before a user is marked offline
USER_ONLINE_TIMEOUT = 300
# Number of seconds that we will keep track of inactive users for before
# their last seen is removed from the cache
USER_LASTSEEN_TIMEOUT = 60 * 60 * 24 * 7
and in profile.html:
<table>
<tr><th>Last Seen</th><td>{% if profile.last_seen %}{{ profile.last_seen|timesince }}{% else %}awhile{% endif %} ago</td></tr>
<tr><th>Online</th><td>{{ profile.online }}</td></tr>
</table>
That's it!
To test cache in the console, to make sure that memcache works fine:
$memcached -vv
$ python manage.py shell
>>> from django.core.cache import cache
>>> cache.set("foo", "bar")
>>> cache.get("foo")
'bar'
>>> cache.set("foo", "zaq")
>>> cache.get("foo")
'zaq'
回答2:
You can have an integer field for each user saying the number of sessions the user has logged in currently. You can increase that by 1 every time the user logs in somewhere, and reduce it by 1 when the user logs out somewhere.
{% if topic.creator.login_count %}
Online
{% else %}
Offline
{% endif %}
This is a simple way to solve this problem. You can refresh this data through an ajax request periodically.
回答3:
As the documentation says:
Even though normally you will check is_autheticated attribute on request.user to find out whether it has been populated by the AuthenticationMiddleware (representing the currently logged-in user), you should know this attribute is True for any User instance.
So to check if user is online I would do something like this:
models.py
class Profile(models.Model):
user = models.OneToOneField(User, related_name='profile')
is_online = models.BooleanField(default=False)
views.py
from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.dispatch import receiver
@receiver(user_logged_in)
def got_online(sender, user, request, **kwargs):
user.profile.is_online = True
user.profile.save()
@receiver(user_logged_out)
def got_offline(sender, user, request, **kwargs):
user.profile.is_online = False
user.profile.save()
And then in your template you would check if user is online:
{% if user.profile.is_online %}
Online
{% else %}
Offline
{% endif %}
Don't forget to return user instance to your template in order for user.profile.is_online
to work.
回答4:
The reason a user appears to always be online is described in the Django documentation:
is_authenticated()
- Always returns
True
... This is a way to tell if the user has been authenticated. This does not imply any permissions, and doesn’t check if the user is active or has a valid session.
There are a number of ways you could achieve this, but none are "build-in".
This question covers the last activity time of a user, and you could use that to check if a user was active in the past few minutes.
Alternatively, you can query the Session table to check if the user has an active session, but this may be inaccurate if you have long session timeouts.
回答5:
Yes it does. But the correct way to check if a user is logged in or not is to use : request.user.is_authenticated. This will return True if the person is logged in other wise False.
eg:
in the template:
{% if request.user.is_authenticated ==True %}
do something awesome.
in views pass request into the template.
return render('url/filename.html',{'any variable name':request})
回答6:
first install django-online-users by running
pip install django-online-users
then in your settings.py
INSTALLED_APPS = [
...
'online_users',]
MIDDLEWARE_CLASSES = (
...
'online_users.middleware.OnlineNowMiddleware',)
Then in your views
import online_users.models
def see_users(self):
user_status = online_users.models.OnlineUserActivity.get_user_activities(timedelta(seconds=60))
users = (user for user in user_status)
context = {"online_users"}`
Pass the context to your template for example
{% for user in users %}
{{user.user}}
{% endfor %}
This will output the users who have been active and online for the last 60 seconds
来源:https://stackoverflow.com/questions/29663777/how-to-check-whether-a-user-is-online-in-django-template