DJANGO - simple-history - как найти таблицу истории из базовой модели, используя стандартный поиск django ORM
Вероятно, это простой ответ, но я не могу найти твердое "да" или "нет" по этому вопросу. Я использую Django simple-history и пытаюсь отфильтровать объекты базовой модели по информации из таблицы истории. Поскольку simple-history генерирует таблицу истории автоматически, и я не создавал для нее модель истории как таковую, я не знаю, работает ли здесь синтаксис поиска django ORM. Мои отношения за столом выглядят так. Вот модель:
class RepairForm(models.Model):
user_id = models.ForeignKey(User, on_delete=models.DO_NOTHING,)
return_number = models.CharField(max_length=200, unique=True)
incident = models.CharField(max_length=100, blank=True)
...
# Simple-history
history = HistoricalRecords()
И я пытаюсь отфильтровать объекты RepairForm по их истории. В качестве примера; только в таблице истории есть поле с именем "history_change_reason". Это просто поле для сохранения строки, которая (в идеале) описывает причину обновления. Ссылаясь на изображение таблицы, которое я связал, я подумал, что мог бы отфильтровать объекты RepairForm, используя таблицу RepairFormHistory, обойдя отношения, которые они оба имели с пользовательской таблицей. Что-то вроде:
RepairForm.objects.filter(user_id__repairformhistory__history_change_reason='Custom Repair form page')
"Repairformhistory" была моей лучшей догадкой относительно того, как называется модель истории (если она есть). Ошибка:
Related Field got invalid lookup: repairformhistory
Я здесь далеко от базы? Могу ли я пройти через такие отношения? даже если для "repairformhistory" нет модели, просто таблица, связанная с оригиналом через пользователя?
2 ответа
Внешний ключ от исторической модели к базовой модели существует по умолчанию, поскольку историческая таблица включает в себя все поля, включенные в базовую модель. Однако, поскольку ключ копируется только как целое число или как uuid, БД не знает, что это внешний ключ. В настоящее время у нас есть атрибут экземпляра в исторической модели, который возвращает версию экземпляра базовой модели исторического экземпляра, но это должно работать только для конкретного экземпляра. То, что я предлагаю сделать здесь, это запросить в исторической таблице идентификаторы, которые вы хотите, а затем отфильтровать базовую модель, используя эти ключи, как показано ниже:
ids = list(HistoricalRepairForm.filter(incident='abc').order_by('id').distinct('id').values_list('id', flat=True))
RepairForm.filter(id__in=ids)
Пытаться
history = RepairForm.history.filter(history_change_reason='Custom Repair form page').first()
или включить user_id
history = RepairForm.history.filter(history_change_reason='Custom Repair form page', history_user_id=user_id).first()
затем получить родительский объект, используя этот идентификатор
# check that there is a result
if history:
# get related object
Repairs = RepairForm.objects.filter(pk=history.pk)