В одном из проектов понадобилось реализовать функцию "Кто на сайте". Средней продолжительности копания привели к модулю django-onlineiser.
$sudo easy install django-onlineuser
далее в settings.py:
#добавляем приложение в список используемых в проекте
INSTALLED_APPS += ('oblineuser')
#регистрируем его middleware в соответствующем списке
MIDDLEWARE_CLASSES += ('onlineuser.middleware.OnlineUserMiddleware')
в нужном html шаблоне подгружаем теги этого приложения и там же отображаем html-код этой приблуды
{% load onlineuser_tags %}
Кто здесь?
{%onlineinfos%}
У меня, чтобы заработало пришлось немного модифицировать код класса из middleware.py, обернув имеющийся там код в try except
class OnlineUserMiddleware:
def process_request(self, request):
try:
user = request.user
ip=request.META['REMOTE_ADDR']
if user.is_authenticated():
o, created = Online.objects.get_or_create(user=user)
o.session_key = ip
else:
o, created = Online.objects.get_or_create(ident=ip)
o.session_key = ip
if not created:
o.save()
except:
return
В результате видим простейшую статистику о гостях и онлайн юзерах.
С первого взгляда все ок и автору приложения в любом случае спасибо.
Но чуть позже стало понятно 2 факта (помимо бага описанного выше):
1. сразу после логаута пользователя счетчик пользователей не уменьшается, а счетик гостей не увеличивается
2. после логина счетчик гостей не уменьшается, хотя счетчик пользователей увеличивается
Не совсем релевантно получается.
Я допилил это приложение с помощью сигналов о логине и логауте:
#этот код я добавил в middleware.py рассматриваемого приложения, хотя можно и любое другое удобное место
from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.dispatch import receiver
@receiver(user_logged_in)
def count_logins(sender,request,user,**kwargs):
ip=request.META['REMOTE_ADDR']
g=Online.objects.get(session_key=ip, user=None)
if(g):
g.delete() #удаляем гостя , после того , как он стал залогиненным юзером
#создаем или обновляем запись в таблице приложения (этот код я скопипастил из имеющегося миддлваре-класса
o, created = Online.objects.get_or_create(user=user)
o.session_key = ip
if not created:
o.save()
@receiver(user_logged_out)
def count_logouts(sender,request,user,**kwargs):
o=Online.objects.get(user=user)
o.delete() #сразу при логауте удаляем запись из таблицы
Если в ближайшее время не придумаю как более красиво это все дело улучшить, отпишу автору или посто форкну это приложение )