vincent - request.user django
¿Cómo obtener la lista de usuarios autenticados? (4)
Me gustaría mostrar la lista de usuarios autenticados.
En la documentación: http://docs.djangoproject.com/en/dev/topics/auth/
modelos de clase. Usuario
is_authenticated () ¶
Siempre regresa True. Esta es una forma de saber si el usuario ha sido autenticado. ...
Puede saber en el lado de la plantilla si el usuario actual está autenticado o no:
{% if user.is_authenticated%} {% endif%}
Pero no encontré la manera de obtener la lista de usuarios autenticados.
¿Alguna idea?
La solución más confiable sería solo la que almacena cuando el usuario inicia o cierra sesión. Vi esta solución y creo que vale la pena compartirla.
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'')
No hay una manera fácil e integrada de hacer lo que quieres que yo sepa. Probaría una combinación de sesiones de vencimiento y filtrado en last_login. Tal vez incluso escriba un administrador personalizado para eso.
Suena similar a esta solución, puede crear un middleware personalizado para hacerlo. Encontré el asombroso OnlineNowMiddleware
aquí.
Donde obtendrás estos;
-
{{ request.online_now }}
=> muestra toda la lista de usuarios en línea. -
{{ request.online_now_ids }}
=> muestra todos los ID de usuario en línea. -
{{ request.online_now.count }}
=> muestra el total de usuarios en línea.
¿Como instalar?
Crea el archivo middleware.py
donde se ha guardado la ubicación de settings.py
, por ejemplo:
projectname/projectname/__init__.py
projectname/projectname/middleware.py
projectname/projectname/settings.py
Luego siguiendo estas líneas;
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)
Finalmente actualice su MIDDLEWARE
dentro del archivo de 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'',
]
Para otras condiciones, también puede verificar que el usuario actual esté en línea o no con:
{% if request.user in request.online_now %}
{# do stuff #}
{% endif %}
Siguiendo con la respuesta de rz, podría consultar el modelo de Session
para las Session
no expiradas, y luego convertir los datos de la sesión en usuarios. Una vez que tenga eso, podría convertirlo en una etiqueta de plantilla que podría representar la lista en una página determinada.
(Todo esto no se ha probado, pero con suerte estará cerca de funcionar).
Obtener todos los usuarios conectados ...
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)
Al usar esto, puede hacer una etiqueta de plantilla de inclusión simple ...
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 %}
Luego, en su página principal, puede usarlo donde desee ...
{% load your_library_name %}
{% render_logged_in_user_list %}
EDITAR
Para aquellos que hablan sobre el problema persistente de 2 semanas, supongo que cualquiera que desee tener un tipo de listado de "usuarios activos" hará uso de la configuración SESSION_EXPIRE_AT_BROWSER_CLOSE
, aunque reconozco que este no es siempre el caso.