Django: введите дату последнего посещения пользователя - программирование
Подтвердить что ты не робот

Django: введите дату последнего посещения пользователя

В Django мы можем получить время последнего входа пользователя с помощью Auth.User.last_login. Это обновляется только тогда, когда пользователь регистрируется с использованием своего имени пользователя/пароля. Предположим, что пользователь уже зарегистрировался, и информация аутентификации сохраняется в файле cookie, поэтому он имеет доступ к сайту без входа в систему. Как мы можем получить дату, когда пользователь ранее посещал сайт? Это было бы полезно для запросов, таких как получение количества новых записей с момента последнего посещения.

4b9b3361

Ответ 1

Пример модели:

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

Добавьте новое промежуточное программное обеспечение в свой файл settings.py:

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

Предупреждение: не проверено, но не требует установки внешних пакетов и всего 5 строк кода.

Смотрите в документах Middleware и пользовательские модели пользователей (начиная с Django 1.5)

Ответ 2

Здесь промежуточное программное обеспечение, которое будет отслеживать активность последнего пользователя и счетчик, разделенных интервалами времени. Использование интервала создает дискретные "сеансы", которые можно отслеживать/подсчитывать вместе с выгодой для минимизации записи в базу данных.

Каждый раз, когда пользователь auth выполняет запрос, он попадает в кеш, чтобы найти их последнего действия, а затем обновить кеш новой меткой времени. Если активность имела разрыв, по крайней мере, "интервал" времени, тогда он обновит временной отметки базы данных.

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, определите, что составляет интервал неактивности, который считается новым логином.
  • Это обновляет объект "UserProfile", у меня есть 1:1 с объектами User, но вы можете обновить любой объект, который вам нравится.
  • Обязательно укажите это в settings.MIDDLEWARE_CLASSES.
  • Обратите внимание, что это промежуточное программное обеспечение использует process_request not process_response в противном случае в зависимости от порядка промежуточного программного обеспечения, APPEND_SLASH может привести к тому, что request.user будет недоступным, как обсуждалось: Объект Django: WSGIRequest нет атрибута "пользователь" на некоторых страницах?

Ответ 4

То же, что и промежуточное программное обеспечение Джона Лемана, но переписано как функция с предложениями Эндрю Свихарта и протестировано на Django 2.2:

 def last_user_activity_middleware(get_response):

    def middleware(request):

        response = get_response(request)

        key = "last-activity"

        if request.user.is_authenticated:

            last_activity = request.session.get(key)

            # If key is old enough, update database.
            too_old_time = timezone.now() - td(seconds=60 * 60)
            if not last_activity or parse(last_activity) < too_old_time:
                MyUser.objects.filter(email=request.user).update(
                    last_visit=timezone.now(),
                    login_count=F('login_count') + 1)

            request.session[key] = timezone.now().isoformat()

        return response

    return middleware

Узнайте больше о написании собственного промежуточного программного обеспечения в официальной документации: https://docs.djangoproject.com/en/2.2/topics/http/middleware/#writing-your-own-middleware