• en
  • Language: ru

Отслеживание пользователей

Запись того, кто из пользователей изменил модель

Существует четыре документированных способа прикрепления пользователей к отслеживаемому изменению:

1. Use the HistoryRequestMiddleware. The middleware sets the User instance that made the request as the history_user on the history table.

2. Use simple_history.admin.SimpleHistoryAdmin. Under the hood, SimpleHistoryAdmin actually sets the _history_user on the object to attach the user to the tracked change by overriding the save_model method.

3. Assign a user to the _history_user attribute of the object as described in the _history_user section.

4. Track the user using an explicit history_user_id, which is described in Manually Track User Model. This method is particularly useful when using multiple databases (where your user model lives in a separate database to your historical model), or when using a user that doesn’t live within the Django app (i.e. a user model retrieved from an API).

Использование _history_user для записи того, кто из пользователей изменил модель

Чтобы обозначить, какой пользователь изменил модель, присвойте модели атрибут _history_user.

Например, если у вас есть поле changed_by в вашей модели, которое записывает, какой пользователь последним изменил модель, вы можете создать свойство _history_user, ссылающееся на поле changed_by:

from django.db import models
from simple_history.models import HistoricalRecords

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    changed_by = models.ForeignKey('auth.User')
    history = HistoricalRecords()

    @property
    def _history_user(self):
        return self.changed_by

    @_history_user.setter
    def _history_user(self, value):
        self.changed_by = value

Интеграция с администратором требует, чтобы вы использовали атрибут _history_user.setter с вашим пользовательским свойством _history_user (см. Интеграция администратора).

Другим вариантом идентификации пользователя изменений является предоставление функции через get_user. Если она предоставлена, она будет вызываться каждый раз, когда history_user необходимо идентифицировать, со следующими аргументами в виде ключевых слов:

  • instance: Текущий изменяемый экземпляр

  • request: При использовании промежуточного программного обеспечения будет предоставлен текущий объект запроса, если он аутентифицирован.

Это очень полезно при использовании register:

from django.db import models
from simple_history.models import HistoricalRecords

class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    changed_by = models.ForeignKey('auth.User')


def get_poll_user(instance, **kwargs):
    return instance.changed_by

register(Poll, get_user=get_poll_user)

Ручное отслеживание модели пользователя

Хотя django-simple-history отслеживает history_user (пользователя, изменившего модель) с помощью внешнего ключа django, бывают случаи, когда мы хотим отследить этого пользователя, но не можем использовать внешний ключ Django.

Примечание: Если вы хотите отслеживать пользовательскую модель пользователя, которая все еще доступна через внешний ключ Django, обратитесь к Change User Model.

Две наиболее распространенные ситуации, когда эта функция будет полезна:

  1. Вы работаете над приложением Django с несколькими базами данных, и ваша таблица истории находится в отдельной базе данных от таблицы пользователей.

  2. Модель пользователя, которую вы хотите использовать для history_user, не живет внутри приложения Django, а доступна только в другом месте (т.е. через вызов API).

Есть три параметра HistoricalRecords или register, которые облегчают возможность ручного отслеживания history_user.

поле history_user_id_field

Экземпляр поля (т.е. IntegerField(null=True) или UUIDField(default=uuid.uuid4, null=True)), который будет уникально идентифицировать ваш объект пользователя. Обычно это тип поля первичного ключа объекта пользователя.

history_user_getter

опционально. Вызываемый объект, который принимает исторический экземпляр модели и возвращает объект history_user. Геттер по умолчанию показан ниже:

def _history_user_getter(historical_instance):
    if historical_instance.history_user_id is None:
        return None
    User = get_user_model()
    try:
        return User.objects.get(pk=historical_instance.history_user_id)
    except User.DoesNotExist:
        return None
history_user_setter

опционально. Вызываемая функция, которая принимает исторический экземпляр и экземпляр пользователя и устанавливает history_user_id на историческом экземпляре. Установщик по умолчанию показан ниже:

def _history_user_setter(historical_instance, user):
    if user is not None:
        historical_instance.history_user_id = user.pk

Изменение модели пользователя

Если вам необходимо использовать другую модель пользователя, отличную от settings.AUTH_USER_MODEL, передайте требуемую модель в user_model. Для этого необходимо _history_user или << 3 >>>, как описано выше.

from django.db import models
from simple_history.models import HistoricalRecords

class PollUser(models.Model):
    user_id = models.ForeignKey('auth.User')


# Only PollUsers should be modifying a Poll
class Poll(models.Model):
    question = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    changed_by = models.ForeignKey(PollUser)
    history = HistoricalRecords(user_model=PollUser)

    @property
    def _history_user(self):
        return self.changed_by

    @_history_user.setter
    def _history_user(self, value):
        self.changed_by = value