В моем приложении Django мне нужно запускать несколько периодических фоновых заданий, когда пользователь входит в систему, и прекращать их выполнение, когда пользователь выходит из системы, поэтому я ищу элегантный способ
- получать уведомления о входе / выходе пользователя
- запросить статус входа пользователя
С моей точки зрения, идеальным решением было бы
- сигнал, посланный каждым
django.contrib.auth.views.login
и... views.logout
- метод
django.contrib.auth.models.User.is_logged_in()
, аналогичный... User.is_active()
или... User.is_authenticated()
В Django 1.1.1 этого нет, и я не хочу исправлять исходный код и добавлять его (все равно не знаю, как это сделать).
В качестве временного решения я добавил is_logged_in
логическое поле в модель UserProfile, которое очищается по умолчанию, устанавливается при первом переходе пользователя на целевую страницу (определенную LOGIN_REDIRECT_URL = '/'
) и запрашивается в последующих запросах. Я добавил его в UserProfile, поэтому мне не нужно создавать и настраивать встроенную модель User только для этой цели.
Мне не нравится это решение. Если пользователь явно нажимает кнопку выхода, я могу снять флажок, но в большинстве случаев пользователи просто покидают страницу или закрывают браузер; снятие флажка в этих случаях мне не кажется простым. Кроме того (это скорее придирка к ясности модели данных), is_logged_in
это относится не к UserProfile, а к модели User.
Кто-нибудь может придумать альтернативные подходы?
Ответы:
Вы можете использовать такой сигнал (я поместил свой в models.py)
from django.contrib.auth.signals import user_logged_in def do_stuff(sender, user, request, **kwargs): whatever... user_logged_in.connect(do_stuff)
См. Django docs: https://docs.djangoproject.com/en/dev/ref/contrib/auth/#module-django.contrib.auth.signals и здесь http://docs.djangoproject.com/en/dev/ темы / сигналы /
источник
models.py
вместо этого, я предлагаю поместить кодsignals.py
и автоматически импортировать его в__init__.py
файл модулей .В дополнение к ответу @PhoebeB: вы также можете использовать
@receiver
такой декоратор:from django.contrib.auth.signals import user_logged_in from django.dispatch import receiver @receiver(user_logged_in) def post_login(sender, user, request, **kwargs): ...do your stuff..
И если вы поместите его
signals.py
в свой каталог приложения, добавьте это вapps.py
:class AppNameConfig(AppConfig): ... def ready(self): import app_name.signals
источник
Один из вариантов может заключаться в том, чтобы обернуть представления входа / выхода Django своими собственными. Например:
from django.contrib.auth.views import login, logout def my_login(request, *args, **kwargs): response = login(request, *args, **kwargs) #fire a signal, or equivalent return response def my_logout(request, *args, **kwargs): #fire a signal, or equivalent return logout(request, *args, **kwargs)
Затем вы используете эти представления в своем коде, а не в Django, и вуаля.
Что касается запроса статуса входа в систему, это довольно просто, если у вас есть доступ к объекту запроса; просто проверьте атрибут пользователя запроса, чтобы узнать, является ли он зарегистрированным пользователем или анонимным пользователем, и бинго. Процитируем документацию Django :
if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.
Если у вас нет доступа к объекту запроса, то определить, вошел ли в систему текущий пользователь, будет сложно.
Редактировать:
К сожалению, вы никогда не получите
User.is_logged_in()
функциональность - это ограничение протокола HTTP. Однако если вы сделаете несколько предположений, вы сможете приблизиться к тому, чего хотите.Во-первых, почему вы не можете получить эту функциональность? Ну, вы не можете отличить того, кто закрывает браузер, или кто-то проводит некоторое время на странице, прежде чем загрузить новую. Невозможно узнать через HTTP, когда кто-то действительно покидает сайт или закрывает браузер.
Итак, у вас есть два варианта, которые не идеальны:
unload
событие Javascript, чтобы поймать, когда пользователь покидает страницу. Однако вам придется написать некоторую осторожную логику, чтобы убедиться, что вы не выходите из системы, когда они все еще перемещаются по вашему сайту.Эти решения беспорядочные и не идеальные, но, к сожалению, они лучшее, что вы можете сделать.
источник
is_logged_in
очень хорошо разбирался в этом вопросе (извиняюсь, я полагаю, что я не очень хорошо прочитал сообщение), но я обновил ответ, чтобы предложить свою помощь в этой области . К сожалению, это немного невозможная проблема.быстрое решение этой проблемы: в _ _ init _ _.py вашего приложения поместите следующий код:
from django.contrib.auth.signals import user_logged_in from django.dispatch import receiver @receiver(user_logged_in) def on_login(sender, user, request, **kwargs): print('User just logged in....')
источник
Единственный надежный способ (который также определяет, когда пользователь закрыл браузер) - обновить некоторые
last_request
поле каждый раз, когда пользователь загружает страницу.У вас также может быть периодический запрос AJAX, который проверяет сервер каждые x минут, если у пользователя открыта страница.
Затем выполните одно фоновое задание, которое получает список недавних пользователей, создает для них задания и очищает задания для пользователей, которых нет в этом списке.
источник
Вывод из системы, в отличие от того, чтобы они явно нажимали кнопку (чего никто не делает), означает выбор времени простоя, которое приравнивается к «выходу из системы». phpMyAdmin использует по умолчанию 15 минут, некоторые банковские сайты используют всего 5 минут.
Самый простой способ реализовать это - изменить время жизни cookie. Вы можете сделать это для всего сайта, указав
settings.SESSION_COOKIE_AGE
. В качестве альтернативы вы можете изменить его для каждого пользователя (на основе некоторого произвольного набора критериев), используяHttpResponse.setcookie()
. Вы можете централизовать этот код, создав свою собственную версиюrender_to_response()
и задав время жизни для каждого ответа.источник
Примерная идея - для этого можно использовать промежуточное ПО. Это промежуточное ПО может обрабатывать запросы и запускать сигнал при запросе соответствующего URL-адреса. Он также может обрабатывать ответы и сигнал огня, когда данное действие действительно успешно.
источник