2013-08-25 18 views
16

W Django możemy uzyskać ostatni zalogowany użytkownik przy użyciu Auth.User.last_login. Jest to aktualizowane tylko wtedy, gdy użytkownik loguje się przy użyciu swojej nazwy użytkownika/hasła. Załóżmy, że użytkownik jest już zalogowany, a dane uwierzytelniające są zapisywane w pliku cookie, dlatego może on uzyskać dostęp do witryny bez logowania. W jaki sposób możemy uzyskać datę, w której użytkownik wcześniej odwiedził witrynę? Byłoby to przydatne w przypadku zapytań, takich jak uzyskanie liczby nowych rekordów od ostatniej wizyty.Django: data ostatniego odwiedzin użytkownika

+0

https://godjango.com/blog/record-last-access-not- just-last-login/jest bardziej efektywny, ponieważ nie robisz dodatkowego wyszukiwania, jak w przypadku oprogramowania pośredniego. –

Odpowiedz

22

Przykład model:

class User(models.Model): 
    last_visit = models.DateTimeField(...) 
    ... 

Przykład middleware, które będą realizowane na wszystkich zalogowanych:

from django.utils.timezone import now 

class SetLastVisitMiddleware(object): 
    def process_response(self, request, response): 
     if request.user.is_authenticated(): 
      # Update last visit time after request finished processing. 
      User.objects.filter(pk=request.user.pk).update(last_visit=now()) 
     return response 

Ad d nowa middleware do Twojej settings.py:

MIDDLEWARE_CLASSES = (
    ... 
    'path.to.your.SetLastVisitMiddleware', 
    ... 
) 

Ostrzeżenie: nie testowane, ale nie wymaga pakietów zewnętrznych mają być zainstalowane i to tylko 5 linii kodu.

Zobacz więcej w docs o Middleware i custom user models (od Django 1.5)

+0

Musisz zwrócić obiekt 'response' na końcu' process_response'. Chociaż django-last-seen jest pakowanym rozwiązaniem, poszedłem z tą odpowiedzią, ponieważ z django-last-seen muszę pamiętać, aby wywołać 'LastSeen.object.when' na każde żądanie. Oczywiście mógłbym umieścić 'LastSeen.object.when' w oprogramowaniu middleware, ale równie dobrze mógłbym napisać własne oprogramowanie pośrednie. – user2233706

3

I would go for django-last-seen

Zastosowanie:

from last_seen.model import LastSeen 

seen = LastSeen.object.when(user=user) 
+0

Dziękuję wszystkim za szybkie odpowiedzi. Pozwól, że wypróbuję django - ostatnio widziałem. Odpowiedź Pythona Fanboya może być wystarczająca, ale muszę być w stanie śledzić w oparciu o "moduły". – user2233706

+0

Wygląda naprawdę ładnie! Czy ten pakiet nadal działa i/lub jest utrzymywany? – ilse2005

+0

Ten pakiet nie działa z najnowszymi wersjami django. – Jakobovski

6

Oto middleware, która będzie śledzić użytkownik Ostatnia aktywność i liczyć oddzielonych odstępach czasu. Korzystanie z przedziału tworzy dyskretne "sesje", które można śledzić/liczyć wraz z korzyścią minimalizacji zapisów do bazy danych.

Za każdym razem, gdy użytkownik uwierzytelniony wykona żądanie, trafi do pamięci podręcznej, aby znaleźć ostatnie działanie, a następnie zaktualizuje pamięć podręczną o nowy znacznik czasu. Jeśli aktywność ma lukę co najmniej "interwał", to zaktualizuje datownik bazy danych .

from datetime import timedelta as td 
from django.utils import timezone 
from django.conf import settings 
from django.db.models.expressions import F  
from <user profile path> import UserProfile 

class LastUserActivityMiddleware(object): 
    KEY = "last-activity" 

    def process_request(self, request): 
     if request.user.is_authenticated(): 
      last_activity = request.session.get(self.KEY) 

      # If key is old enough, update database. 
      too_old_time = timezone.now() - td(seconds=settings.LAST_ACTIVITY_INTERVAL_SECS) 
      if not last_activity or last_activity < too_old_time: 
       UserProfile.objects.filter(user=request.user.pk).update(
         last_login=timezone.now(), 
         login_count=F('login_count') + 1) 

      request.session[self.KEY] = timezone.now() 

     return None 

Komentarze:

  1. Jak zdefiniować settings.LAST_ACTIVITY_INTERVAL_SECS określić, co stanowi przedział braku aktywności uważany za nowy logowania.
  2. To aktualizuje obiekt "UserProfile", który mam 1: 1 z moimi obiektami użytkownika, ale możesz zaktualizować dowolny obiekt, który Ci odpowiada.
  3. Pamiętaj, aby uwzględnić to w settings.MIDDLEWARE_CLASSES.
  4. Uwaga ta pośredniczące stosuje process_request nie process_response inaczej w zależności od warstwy pośredniej kolejności APPEND_SLASH może powodować request.user być niedostępny, jak omówiono: Django: WSGIRequest' object has no attribute 'user' on some pages?
+0

Musiałem dodać 'from dateutil.parser importować parse' i zastąpić' if not last_activity lub last_activity

+0

Zapomniałem wspominając dlaczego: sesje Django najwyraźniej wymagają danych szeregowalnych JSON, które nie są tak długie, jak timezone.now(), więc musiałem przechowywać je jako ciąg przy użyciu datetime.isoformat() zamiast tego i parsować je z powrotem w datetime. –

Powiązane problemy