02.09.2019       Выпуск 298 (02.09.2019 - 08.09.2019)       Статьи

Django. Как добавить статус онлайн на сайте

Статья о том, как добавить статус онлайн у пользователя. Поможет другим пользователям видеть, на сайте ли сейчас их друзья и знакомые. Для этого немного препарируем Backend аутентификации.

Читать>>




Экспериментальная функция:

Ниже вы видите текст статьи по ссылке. По нему можно быстро понять ссылка достойна прочтения или нет

Просим обратить внимание, что текст по ссылке и здесь может не совпадать.

Долгое время не добавлял подобный функционал на сайте по той простой причине, что не знал, с какой бы стороны к этому подойти, поскольку хотелось бы обрабатывать данную информацию в одном единственном месте, а не в каждом View.

Со временем я начал модифицировать Backend классы для сайта и решение пришло само собой. Нужно было всего лишь модифицировать каждый бэкенд аутентификации, который используется на сайте. И переписать метод get_user, в котором будет сохраняться информация о последнем запросе пользователя к сайту. А статус онлайн можно сохранять последние 15 минут, потом статус будет оффлайн.

А дату последнего запроса можно хранить либо в профиле пользователя, который будет OneToOne моделью к пользователю, либо переопределить модель пользователя. Я выбрал вариант с переопределением модели пользователя.

my_auth

Создадим наш собственный модуль аутентификации my_auth, если вы его ещё не создали

python manage.py startapp my_auth

models.py

После чего переопределим модель пользователя

# -*- coding: utf-8 -*-

from django.contrib.auth.models import AbstractUser
from django.contrib.humanize.templatetags.humanize import naturaltime
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _


class User(AbstractUser):

    last_online = models.DateTimeField(blank=True, null=True)

    # В данном методе проверяем, что дата последнего посещения не старше 15 минут
    def is_online(self):
        if self.last_online:
            return (timezone.now() - self.last_online) < timezone.timedelta(minutes=15)
        return False

    # Если пользователь посещал сайт не более 15 минут назад, 
    def get_online_info(self):
        if self.is_online():
            # то возвращаем информацию, что он онлайн
            return _('Online')
        if self.last_online:
            # иначе пишем сообщение о последнем посещении
            return _('Last visit {}').format(naturaltime(self.last_online))
            # Если вы только недавно добавили информацию о посещении пользователем сайта
            # то для некоторых пользователей инфомации о посещении может и не быть, вернём информацию, что последнее посещение неизвестно
        return _('Unknown')

backends.py

Далее напишем собственный бэкенд аутентификации, который будет заменять бэкенд Django.

# -*- coding: utf-8 -*-

from django.contrib.auth import get_user_model
from django.utils import timezone


class MyBackend:

    def get_user(self, user_id):
        try:
            user = get_user_model().objects.get(pk=user_id)
            user.last_online = timezone.now()  # При запросе пользователя выполним обновлении даты и времени последнего посещения
            user.save(update_fields=['last_online'])
            return user
        except get_user_model().DoesNotExist:
            return None

settings.py

Не забываем зарегистрировать наше приложение ...

INSTALLED_APPS = [
    'my_auth.apps.MyAuthConfig',
    ...
]

... и добавить бэкенд аутентификации

AUTHENTICATION_BACKENDS = (
    'my_auth.backends.MyBackend',
    'django.contrib.auth.backends.ModelBackend',
)

Заключение

Теперь при каждом запросе пользователя к сайту у вашего пользователя будет обновляться информация о его последнем посещении.

И вы сможете в шаблоне делать у пользовтелей в контенте, находится ли он онлайн или нет. Например так, чтобы добавить значок Online у аватарки

{% if user.is_online %}
    <div class="online"></div>
{% endif %}

или так отображать информацию о его онлайн статусе.

<span class="text-muted">{{ user_profile.get_online_info }}</span>

Возможный недостаток данного метода заключается в том, что пользователь может открыть страницу и ничего не делать целый час на ней.
Но в моём случае это не является проблемой, поскольку я каждую минуту вызываю проверку статусной информации у аутентифицированного пользователя, таким образом, пока страница пользователя остаётся открытой, каждую минуту обновляется его статус онлайн.






Разместим вашу рекламу

Пиши: mail@pythondigest.ru

Нашли опечатку?

Выделите фрагмент и отправьте нажатием Ctrl+Enter.

Система Orphus