Отслеживание пользователей¶
Запись того, кто из пользователей изменил модель¶
Существует четыре документированных способа прикрепления пользователей к отслеживаемому изменению:
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.
Две наиболее распространенные ситуации, когда эта функция будет полезна:
Вы работаете над приложением Django с несколькими базами данных, и ваша таблица истории находится в отдельной базе данных от таблицы пользователей.
Модель пользователя, которую вы хотите использовать для
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