Мое решение:
да. Вот простое и быстрое решение, которому я следую:
Я создаю три модели, похожие на это:
class my_super_abstract_model(Model):
#All fields I need to keep a history for:
fieldA = models.FloatField()
fieldB = models.FloatField()
class Meta:
abstract = True
class my_model( my_super_abstract_model ):
def has_history( self ):
return self.my_model_history_set.count() > 0
class my_model_history( my_super_abstract_model ):
reason = models.TextField()
history_entry_for = models.ForeignKey( my_model )
Я настроил сигнал:
pre_save.connect( create_history,
sender = my_model_history )
и 'create history' для вызова по сигналу pre_save () перед сохранением в my_model_history:
def create_history(sender, **kwargs):
#get variables passed by the pre-save signal:
history_model = kwargs['instance']
# Get main model object
main_model = history_model.history_entry_for
# swap all common fields between history edit and main model (except id)
main_model_fields = [f.name for f in main_model._meta.fields]
history_model_fields = [f.name for f in history_model._meta.fields]
field_index = list( [f for f in history_model_fields if f in main_model_fields and f != 'id' and f != 'created_date' ] )
#loop thru to swap values:
for field_name in field_index:
temp = getattr(main_model, field_name)
setattr( main_model, field_name, getattr( history_model, field_name ) )
setattr( history_model, field_name, temp)
# After the swap, save main model object here
main_model.save()
Всякий раз, когда пользователь нажимает на строку my_model для редактирования, я использую my_model_history, чтобы сгенерировать форму редактирования и заполнить ее значениями из выбранной пользователем строки. (Для этого написали вид и шаблон)
Таким образом, форма редактирования теперь будет иметь:
- поле А заполнено значениями от
Строка данных my_model
- поле B заполнено значениями от
Строка данных my_model
- Причина - пустое текстовое поле
- history_entry_for - скрыто от просмотра
Пользователь теперь может редактировать поле A / fieldB. Введите причину. Нажмите сохранить, чтобы активировать сигнал выше.
Перед сохранением
- Сигнал поменяет местами значения между
основная модель (старые значения) и
Модель истории (Новые значения)
- Заменить и сохранить основной ряд моделей
(с новыми значениями).
- Вставьте и сохраните новую строку в
модель истории (со старыми ценностями)
с причиной.
Надеюсь, это поможет. Дайте мне знать, если есть еще вопросы.