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