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

Auth, Django, Backend, Python

Содержание

Долгое время не добавлял подобный функционал на сайте по той простой причине, что не знал, с какой бы стороны к этому подойти, поскольку хотелось бы обрабатывать данную информацию в одном единственном месте, а не в каждом 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>

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

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.
- блог компании
Поддержать автора Donate

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
Donate

Здравствуйте, уважаемые пользователи EVILEG !!!

Если сайт вам помог, то поддержите разработку сайта финансово, пожалуйста.

Вы можете сделать это следующими способами:

Спасибо, Евгений Легоцкой

A
29 марта 2020 г. 12:14
Alexanderv66

C++ - Тест 003. Условия и циклы

  • Результат:71баллов,
  • Очки рейтинга1
A
29 марта 2020 г. 12:05
Alexanderv66

C++ - Тест 004. Указатели, Массивы и Циклы

  • Результат:80баллов,
  • Очки рейтинга4
DE
28 марта 2020 г. 15:13
Denis Erokhin

C++ - Тест 005. Структуры и Классы

  • Результат:100баллов,
  • Очки рейтинга10
Последние комментарии
27 марта 2020 г. 14:40
Евгений Легоцкой

Добрый день. В конце пятой статьи скачать можете.
27 марта 2020 г. 14:28
mkdir _

Здравствуйте, а можно, пожалуйста, ссылку на целые исходники, если есть?
27 марта 2020 г. 4:36
Евгений Легоцкой

Скорее всего также, как и для установки всех остальных переменых в CMake, через использование set
27 марта 2020 г. 2:47
Андрей Янкович

Ошибка с ярлыками в Windows исправлена в версиии 1.4.0.4
Сейчас обсуждают на форуме
30 марта 2020 г. 4:16
Евгений Легоцкой

Попробуйте запустить через плейлист, а не через setMedia. Пример есть в этой статье
30 марта 2020 г. 3:25
Евгений Легоцкой

Добрый день. Почитайте документацию, в исходниках этой библиотеки есть исходнные классы логгеров. Вам наверняка достаточно только правильно вызвать пару функций, чтобы задать имя файла…
30 марта 2020 г. 3:17
Евгений Легоцкой

Нет, не нужно ничего умножать, если у вас включена поддержа High DPI в приложении а QML, то достаточно держать в памяти, что все значения задаются в DPI, и просто задаёте значения равные DPI сра…
27 марта 2020 г. 10:00
Михаиллл

Оказывается нужно сделать столбец уникальным ALTER TABLE public.drivers ADD UNIQUE (agregator1_id); Потом так работает INSERT INTO drivers( name_driver, surname, middle_name, agr…
s
27 марта 2020 г. 8:25
shuric

Спасибо за ответы. Скорее всего оставлю на неопределенное время под macOS. Хоть будет полезно другим начинающим разработчикам.
EVILEG
О нас
Услуги
© EVILEG 2015-2019
Рекомендует хостинг TIMEWEB