25👍
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'
8👍
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.
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.
- Django – reverse lookups with ManyToManyField
- Disable caching for a view or url in django
- How to make TimeField timezone-aware?
- How to install gnu gettext (>0.15) on windows? So I can produce .po/.mo files in Django
- Python 2 -> 3 Django migration causes field parameter type change
2👍
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
- Quantize result has too many digits for current context
- What are the valid values for a django URL field?
- Efficient function to retrieve a queryset of ancestors of an mptt queryset
- Sphinx-apidoc on django build html failure on `django.core.exceptions.AppRegistryNotReady`
- How can I compare two fields of a model in a query?
1👍
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.
- Celerybeat not executing periodic tasks
- How to give foreign key name in django
- How can I add a test method to a group of Django TestCase-derived classes?
1👍
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})
- Django-rest-swagger nested serializers with readonly fields not rendered properly
- How to debug: Internal Error current transaction is aborted, commands ignored until end of transaction block
- A good collaborative filtering/matching/recommendation library for Python/Django?
- Good ways to name django projects which contain only one app