- 1. менің_автоматтылығым
- 1. models.py
- 2. backends.py
- 3. settings.py
- 2. Қорытынды
Мен мұндай функционалдылықты сайтқа ұзақ уақыт қоспадым, себебі мен бұған қалай қарау керектігін білмедім, өйткені мен бұл ақпаратты әр Көріністе емес, бір жерде өңдегім келеді.
Уақыт өте келе мен сайтқа арналған Backend сыныптарын өзгерте бастадым және шешім өздігінен келді. Тек сайтта қолданылатын әрбір аутентификация серверін өзгерту қажет болды. Және get_user әдісін қайта жазыңыз, ол пайдаланушының сайтқа соңғы кіруі туралы ақпаратты сақтайды. Желідегі күйді соңғы 15 минут ішінде сақтауға болады, содан кейін күй желіден тыс болады.
Соңғы сұраудың күні пайдаланушы үшін OneToOne үлгісі болатын пайдаланушы профилінде сақталуы мүмкін немесе пайдаланушы үлгісін қайта анықтауға болады. Мен пайдаланушы үлгісін қайта анықтау опциясын таңдадым.
менің_автоматтылығым
Егер сіз әлі жасалмаған болсаңыз, 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) # In this method, check that the date of the last visit is not older than 15 minutes def is_online(self): if self.last_online: return (timezone.now() - self.last_online) < timezone.timedelta(minutes=15) return False # If the user visited the site no more than 15 minutes ago, def get_online_info(self): if self.is_online(): # then we return information that he is online return _('Online') if self.last_online: # otherwise we write a message about the last visit return _('Last visit {}').format(naturaltime(self.last_online)) # If you have only recently added information about a user visiting the site # then for some users there may not be any information about the visit, we will return information that the last visit is unknown 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() # At the request of the user, we will update the date and time of the last visit 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', )
Қорытынды
Енді пайдаланушы сайтқа кірген сайын сіздің пайдаланушы оның соңғы кіруі туралы ақпаратпен жаңартылады.
Сіз шаблондағы мазмұнды желіде болғанына қарамастан, пайдаланушылармен жасай аласыз. Мысалы, аватарға «Онлайн» белгішесін қосу үшін
{% if user.is_online %} <div class="online"></div> {% endif %}
немесе оның желідегі күйі туралы ақпаратты көрсетеді.
<span class="text-muted">{{ user_profile.get_online_info }}</span>
Бұл әдістің ықтимал кемшілігі - пайдаланушы бетті ашып, бір сағат бойы ештеңе істей алмайды.
Бірақ менің жағдайда бұл проблема емес, өйткені мен пайдаланушының беті ашық болған кезде оның желідегі күйі әр минут сайын жаңартылып тұруы үшін аутентификацияланған пайдаланушының күйі туралы ақпаратты минут сайын шақырамын.
Доброго дня. А можно реализовать с помощью этой фичи вывод блок "Пользователи онлайн" и окрашивать взависимости от группы юзера? Как в скрине ниже.
Screenshot_36.png
Добрый день.
Конечно, нужно будет только шаблонный тег написать, который будет забирать всех пользователей онлайн, проверяя группу текущего пользователя.
У меня пользователи онлайн на отдельной странице в разделе пользователей.
Здравствуйте. как внедрить эту систему если у меня уже есть авторизация и всё с ней связанное? что бы это не перекрывало весь мой код?
Добрый день. Вам нужно скопировать в класс AdvUser содержимое класса User из статьи. Полностью весь класс копировать не требуется.
Полагаю, что в файле settings.py у вас уже переопределён класс пользователя на ваш в переменной AUTH_USER_MODEL
Остальной код написан относительно универсально, достаточно лишь добавить файлы с содержимым как в статье в ваше существующее app аутентификации.
Также не забудьте создать миграцию и применить её, чтобы добавилось новое поле в таблице пользователя.
Большое спасибо!
И так , не все получилось. Сделал как вы говорили. И у меня как и раньше перебивает мою авторизацию. При входе в admin Вот эта ошибка
после чего я удалил из settings поле 'manager_school.backends.MyBackend'. Меня пустило. Но дело в том что(понятно что оно без этой строчки работать не будет) если я дату указываю в поле админки то мне выдаёт что человек онлайн.И даже если я выйду он всё-равно online. без этой строчки не отдаботает
И я понимаю что дело в 'manager_school.backends.MyBackend' этой строчке . но Как же мне сделать что бы он не заменял собой все настройки авторизации...?
Длительность сохранения статуса онлайн от последнего запроса страницы составляет 15 минут.
Можете уменьшить на одну минуту и посмотреть результат. Вполне возможно, что у вас всё работает.
Данная система статуса онлайн не совершенна, поскольку требует периодического обращения к серверу. Чтобы обновлять время последнего статуса онлайн. У меня эта проблема решается за счёт обращения к серверу раз в одну минуту для проверки уведомлений через JavaScript. Остальные разработчики решают эту часть своими способоами, как у них это выходит.
Да ещё.
Покажите код ваших бэкендов аутентификации, а также как скопировали код класса MyBackend
Помимо прочего, какую версию Джанго используете?
P/S/ Используйте диалог вставки программного кода, чтобы был код с разметкой. Не надо вставлять изображения кода, на любьом форуме это считается плохим тоном.
P/P/S/ И я просил на форуме задать вопрос, а не в комментариях к статье ))
Спасибо за ответ. уменьшил время до 14 минут и до 10 минут , ошибка осталась та же 'MyBackend' object has no attribute 'authenticate'
MyBackend
Версия Django 3.0.8
бэк аутентификации
Извиняюсь. Время здесь влияние не оказывает, это я ответил по поводу сохранения статуса онлайн.
Надо подумать. Я писал этот статус онлайн для Django 2. Вполне возможно, что для третьей версии там используется несколько иной механизм бэкендов.
Смогу посмотреть это только после работы уже.
Я нашел ответ на ошибку
Ясно, значит для Django 3 обязательно наследование от BaseBackend при создание бэкенда аутентификации.
Скорее всего отсутствовал метод authenticate, который присутсвует при наследовании от BaseBackend
Хорошая статья для создания собственной батарейки для Django. Правда под каждую версию фреймворка приходится допиливать код бэкенда. Так как для версии Django 4 если наследовать бэкенд от BaseBackend то обновление статуса не происходит. Он просто проходит мимо метода get_user. По этому наследование лучше делать от ModelBackend и всё начинает работать.
Остальной весь код рабочий! Проверено на Django 4.
Сделал всё как описано но при создании миграций возникает ошибка:
SystemCheckError: System check identified some issues:
ERRORS:
auth.User.groups: (fields.E304) Reverse accessor for 'auth.User.groups' clashes with reverse accessor for 'users.User.groups'.
HINT: Add or change a related_name argument to the definition for 'auth.User.groups' or 'users.User.groups'.
auth.User.user_permissions: (fields.E304) Reverse accessor for 'auth.User.user_permissions' clashes with reverse accessor for 'users.User.user_permissions'.
HINT: Add or change a related_name argument to the definition for 'auth.User.user_permissions' or 'users.User.user_permissions'.
users.User.groups: (fields.E304) Reverse accessor for 'users.User.groups' clashes with reverse accessor for 'auth.User.groups'.
HINT: Add or change a related_name argument to the definition for 'users.User.groups' or 'auth.User.groups'.
users.User.user_permissions: (fields.E304) Reverse accessor for 'users.User.user_permissions' clashes with reverse accessor for 'auth.User.user_permissions'.
HINT: Add or change a related_name argument to the definition for 'users.User.user_permissions' or 'auth.User.user_permissions'.
А вы создали в settings.py?
А так же во всех моделях где есть внешний ключ на юзера нужно ставить
Евгений у меня вопрос. В общем и целом оно всё работает. Но есть маленький затык. Это так сказать дело в том что при переключении языка "Last visit" переводится а вот то что отдаёт функция "naturaltime" нет. Есть какая то возможность это исправить? Или нужно переписать код этой самой функции?
Я обычно использую localtime и всё работает.