Как получить список аутентифицированных пользователей?
Я хотел бы отобразить список пользователей, прошедших проверку подлинности.
В документации: http://docs.djangoproject.com/en/dev/topics/auth/
class models.User
is_authenticated() ¶
Всегда возвращает True. Это способ узнать, прошел ли аутентификация пользователя....
Вы можете знать, что на стороне шаблона находится текущий. Пользователь аутентифицирован или нет:
{%, если user.is_authenticated%} {% endif%}
Но я не нашел способ получить список аутентифицированных пользователей.
Любая идея?
Ответы
Ответ 1
Идем вместе с ответом rz, вы можете запросить модель Session
для сеансов без истечения срока действия, а затем перевести данные сеанса в пользователей. После этого вы можете превратить его в тег шаблона, который может отображать список на любой заданной странице.
(Это все непроверено, но, надеюсь, будет близко к работе).
Получить всех зарегистрированных пользователей...
from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
from django.utils import timezone
def get_all_logged_in_users():
# Query all non-expired sessions
# use timezone.now() instead of datetime.now() in latest versions of Django
sessions = Session.objects.filter(expire_date__gte=timezone.now())
uid_list = []
# Build a list of user ids from that query
for session in sessions:
data = session.get_decoded()
uid_list.append(data.get('_auth_user_id', None))
# Query all logged in users based on id list
return User.objects.filter(id__in=uid_list)
Используя это, вы можете сделать простой тег шаблона включения...
from django import template
from wherever import get_all_logged_in_users
register = template.Library()
@register.inclusion_tag('templatetags/logged_in_user_list.html')
def render_logged_in_user_list():
return { 'users': get_all_logged_in_users() }
logged_in_user_list.html
{% if users %}
<ul class="user-list">
{% for user in users %}
<li>{{ user }}</li>
{% endfor %}
</ul>
{% endif %}
Затем на главной странице вы можете просто использовать его там, где хотите...
{% load your_library_name %}
{% render_logged_in_user_list %}
ИЗМЕНИТЬ
Для тех, кто говорит о 2-недельной постоянной проблеме, я предполагаю, что любой желающий иметь тип "активных пользователей" будет использовать SESSION_EXPIRE_AT_BROWSER_CLOSE
, хотя я понимаю, что это не всегда так.
Ответ 2
Наиболее надежным решением будет только то, что вы храните, когда пользователь входит в систему или выходит из системы. Я видел это решение, и я думаю, что его стоит поделиться.
models.py
class LoggedUser(models.Model):
user = models.ForeignKey(User, primary_key=True)
def __unicode__(self):
return self.user.username
def login_user(sender, request, user, **kwargs):
LoggedUser(user=user).save()
def logout_user(sender, request, user, **kwargs):
try:
u = LoggedUser.objects.get(user=user)
u.delete()
except LoggedUser.DoesNotExist:
pass
user_logged_in.connect(login_user)
user_logged_out.connect(logout_user)
views.py
logged_users = LoggedUser.objects.all().order_by('username')
Ответ 3
Нет простого, встроенного способа делать то, что вы хотите, о котором я знаю. Я попробую сочетание истекающих сессий и фильтрации на last_login. Возможно, даже напишите для этого пользовательский менеджер.
Ответ 4
Звуки, похожие на это решение, вы можете создать собственное промежуточное программное обеспечение для этого. Я нашел awesome OnlineNowMiddleware
здесь.
Где вы их получите:
-
{{ request.online_now }}
= > отобразить список всех пользователей онлайн.
-
{{ request.online_now_ids }}
= > отображать все онлайн-идентификаторы пользователей.
-
{{ request.online_now.count }}
= > отображение всех онлайн-пользователей.
Как настроить?
Создайте файл middleware.py
, где было сохранено местоположение settings.py
, например:
projectname/projectname/__init__.py
projectname/projectname/middleware.py
projectname/projectname/settings.py
Затем, следуя этим строкам:
from django.core.cache import cache
from django.conf import settings
from django.contrib.auth.models import User
from django.utils.deprecation import MiddlewareMixin
ONLINE_THRESHOLD = getattr(settings, 'ONLINE_THRESHOLD', 60 * 15)
ONLINE_MAX = getattr(settings, 'ONLINE_MAX', 50)
def get_online_now(self):
return User.objects.filter(id__in=self.online_now_ids or [])
class OnlineNowMiddleware(MiddlewareMixin):
"""
Maintains a list of users who have interacted with the website recently.
Their user IDs are available as ``online_now_ids`` on the request object,
and their corresponding users are available (lazily) as the
``online_now`` property on the request object.
"""
def process_request(self, request):
# First get the index
uids = cache.get('online-now', [])
# Perform the multiget on the individual online uid keys
online_keys = ['online-%s' % (u,) for u in uids]
fresh = cache.get_many(online_keys).keys()
online_now_ids = [int(k.replace('online-', '')) for k in fresh]
# If the user is authenticated, add their id to the list
if request.user.is_authenticated():
uid = request.user.id
# If their uid is already in the list, we want to bump it
# to the top, so we remove the earlier entry.
if uid in online_now_ids:
online_now_ids.remove(uid)
online_now_ids.append(uid)
if len(online_now_ids) > ONLINE_MAX:
del online_now_ids[0]
# Attach our modifications to the request object
request.__class__.online_now_ids = online_now_ids
request.__class__.online_now = property(get_online_now)
# Set the new cache
cache.set('online-%s' % (request.user.pk,), True, ONLINE_THRESHOLD)
cache.set('online-now', online_now_ids, ONLINE_THRESHOLD)
Наконец обновите свой MIDDLEWARE
внутренний файл projectname/projectname/settings.py
:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
....
# Custom middleware
'projectname.middleware.OnlineNowMiddleware',
]
Для других условий вы также можете проверить, что текущий пользователь находится в сети или нет:
{% if request.user in request.online_now %}
{# do stuff #}
{% endif %}