2013-08-25 3 views
16

Django에서는 Auth.User.last_login을 사용하여 마지막으로 로그인 한 사용자를 얻을 수 있습니다. 사용자 이름/비밀번호를 사용하여 로그인 할 때만 업데이트됩니다. 사용자가 이미 로그인되어 있고 인증 정보가 쿠키에 저장되어 있으므로 로그인하지 않고 사이트에 액세스 할 수 있다고 가정합니다. 사용자가 이전에 사이트를 방문한 날짜를 어떻게 확인할 수 있습니까? 이것은 마지막 방문 이후에 새로운 레코드의 수를 얻는 것과 같은 쿼리에 유용합니다.Django : 마지막 사용자 방문 날짜를 받으십시오.

+0

https://godjango.com/blog/record-last-access-not- just-last-login /은 미들웨어의 경우와 같이 추가 조회를하지 않기 때문에보다 효율적입니다. –

답변

22

예 모델 :

class User(models.Model): 
    last_visit = models.DateTimeField(...) 
    ... 
모든 로그인 한 사용자에 대해 실행됩니다

예 미들웨어 :

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 

광고 D 당신의 settings.py에 새 미들웨어 :

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

경고 :는 테스트하지,하지만 설치 될 외부 패키지를 필요로하지 않으며, 코드의 5 라인입니다.

다음은 사용자가 마지막으로 활동을 추적하고 시간 간격으로 구분 계산하는 미들웨어의 Middlewarecustom user models

+0

'process_response'의 끝에서'response' 객체를 반환해야합니다. django-last-seen는 패키지 된 솔루션이지만, Django-last-seen에서는 매 요청시마다 LastSeen.object.when를 호출해야한다는 점을 기억해야하기 때문에이 대답을했습니다. 물론 미들웨어에'LastSeen.object.when'을 넣을 수는 있지만 내 자신의 미들웨어를 작성할 수도 있습니다. – user2233706

3

I would go for django-last-seen

사용법 :

from last_seen.model import LastSeen 

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

빠른 답변을 보내 주셔서 감사합니다. 내가 장고 - 마지막 - 밖으로 보자. Python Fanboy의 대답은 충분할 수 있지만 "모듈"을 기반으로 추적 할 수 있어야합니다. – user2233706

+0

정말 멋진데! 이 패키지는 여전히 작동 및 유지 관리 중입니까? – ilse2005

+0

이 패키지는 더 이상 최신 버전의 django에서 작동하지 않습니다. – Jakobovski

6

(장고 1.5 이후)에 대한 문서에서 자세한 내용을 참조하십시오. 간격을 사용하면 데이터베이스에 대한 쓰기를 최소화하는 이점과 함께 추적/계산할 수있는 개별 "세션"을 생성합니다.

인증 사용자가 요청을 수행 할 때마다 캐시를 ​​방문하여 마지막 활동을 찾은 다음 캐시에 새 타임 스탬프를 업데이트합니다. 활동에 간격 "간격"이상이있는 경우 데이터베이스 타임 스탬프가 업데이트됩니다.

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 

댓글 : 당신이 settings.LAST_ACTIVITY_INTERVAL_SECS이 새 로그인으로 간주 비 활동의 간격을 구성하는 결정을 정의하는 방법

  1. .
  2. 이렇게하면 사용자 개체가 1 : 1 인 "UserProfile"개체가 업데이트되지만 사용자가 원하는 개체를 업데이트 할 수 있습니다.
  3. settings.MIDDLEWARE_CLASSES에 반드시 기입하십시오.
  4. 참고이 미들웨어 바와 같이 process_request는 달리 process_response 미들웨어 주문에 따라, APPEND_SLASH를 사용할 수 request.user 발생할 수없는 사용 Django: WSGIRequest' object has no attribute 'user' on some pages?
+0

'from dateutil.parser import parse'를 추가하고'last_activity 또는 last_activity

+0

잊어 버렸습니다. 이유는 : 장고 세션은 분명히 datetime.isoformat()을 사용하여 문자열로 저장하고 datetime으로 다시 구문 분석해야하므로 JSON 직렬 가능 데이터가 필요합니다. timezone.now()와 같은 datetime은 필요하지 않습니다. –

관련 문제