В моем приложении 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 с этой целью только.
Мне не нравится это решение. Если пользователь explicitely нажимает кнопку выхода из системы, я могу очистить флаг, но большую часть времени, пользователи просто оставляют страницу или закрывают браузер; очистка флага в этих случаях не кажется прямой мне. Кроме того (это - мелочные придирки ясности довольно модели данных, хотя), is_logged_in
не входит в состав UserProfile, но модели User.
Кто-либо может думать об альтернативных подходах?
Одним из вариантов может быть обертывание представлений входа/выхода из системы 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
, чтобы поймать, когда пользователь покидает страницу. Однако, Вы должны написать осторожную логику, чтобы убедиться, что Вы не выходите из системы, когда пользователь все еще навигационирует по Вашему сайту.Эти решения грязные и не идеальные, но они - лучшее, что вы можете сделать, к сожалению.
. Единственный надежный способ (который также определяет, когда пользователь закрыл браузер) - обновлять некоторое поле last_request
каждый раз, когда пользователь загружает страницу.
Вы также можете иметь периодический AJAX-запрос, который пингнет сервер каждые x минут, если у пользователя открыта страница.
Затем иметь одно фоновое задание, которое получает список последних пользователей, создает задания для них и очищает задания для пользователей, не присутствующих в этом списке.
.Вывод из системы, в отличие от явного нажатия на кнопку (чего никто не делает), означает выбор времени простоя, которое равнозначно "выходу из системы". По умолчанию phpMyAdmin использует 15 минут, некоторые банковские сайты используют всего 5 минут.
Самым простым способом реализации этого параметра было бы изменение времени жизни cookie-файлов. Вы можете сделать это для всего вашего сайта, указав settings.SESSION_COOKIE_AGE
. В качестве альтернативы, вы можете изменить его для каждого пользователя (на основе некоторого произвольного набора критериев), используя HttpResponse.setcookie()
. Вы можете централизовать этот код, создав свою собственную версию render_to_response()
и установив время жизни для каждого ответа.
Грубая мысль - для этого можно использовать промежуточное программное обеспечение. Это промежуточное программное обеспечение может обрабатывать запросы и сигналы пожара, когда запрашивается соответствующий URL. Оно также может обрабатывать ответы и сигнал пожара, когда заданное действие действительно выполнено.
.