Взгляните на django-reversion
. Он обеспечивает контроль версий для моделей Django. Может быть легко добавлен в существующий проект.
Он не использует подход "текущего" указателя. Вместо этого он сериализует объект каждый раз при его сохранении и сохраняет его в отдельной Version
модели с общим внешним ключом, указывающим на этот объект. (Поля отношений по умолчанию сериализованы как первичные ключи.) Кроме того, он позволяет гибко группировать Version
в Revision
.
Итак, вы можете сделать что-то вроде этого:
- Когда пользователь загружает CSV, просто сохраните изменения как обычно, но добавьте
@revision.create_on_success
декоратор к функции, которая выполняет импорт, чтобы любые изменения в записях, сделанные этой функцией, сохранялись под одной ревизией.
- Когда пользователь нажимает «Отменить», вы просто отменяете последнюю версию.
Вот как это можно сделать:
@revision.create_on_success
def import_csv(request, csv):
# Old versions of all objects save()d here will
# belong to single revision.
def undo_last_csv_import(request):
# First, get latest revision saved by this user.
# (Assuming you create revisions only when user imports a CSV
# and do not version control other data.)
revision = Revision.objects.filter(user=request.user)\
.order_by('-date_created')[0]
# And revert it, delete=True means we want to delete
# any newly added records as well
revision.revert(delete=True)
Он основан на том факте, что вы создаете редакции только тогда, когда пользователь импортирует CSV. Это означает, что если вы планируете также управлять версиями других данных, вам нужно будет реализовать какой-то флаг, с помощью которого вы можете получить записи, затронутые последним импортом. Затем вы можете получить запись по этому флагу, получить ее последнюю сохраненную версию и вернуть всю ревизию, к которой принадлежит эта версия. Нравится::
def undo_last_csv_import(request):
some_record = Record.objects.by_user(request.user).from_the_last_import()[0]
latest_saved_version_of_some_record = Version.objects.get_for_date(
some_record,
datetime.now(), # The latest saved Version at the moment.
)
# Revert all versions that belong to the same revision
# as the version we got above.
latest_saved_version_of_some_record.revision.revert()
Это не красивое решение, наверняка есть способы сделать это лучше с помощью этого приложения. Я рекомендую взглянуть на код, чтобы лучше понять, как работает django-reversion
- очень хорошо документирован, невозможно найти функцию без строки документации. ^ _ ^ d
(Документация тоже хороша, но оказалась для меня немного вводящей в заблуждение, т.е. они пишут Version.objects.get_for_date(your_model, date)
, где your_model на самом деле является экземпляром модели.)
Обновление: активно поддерживается django-reversion, поэтому не стоит сильно полагаться на приведенный выше код, а лучше проверьте их wiki о том, как управлять версиями и редакциями вне администратора django. Например, комментарии к ревизии уже поддерживаются, что может немного упростить ситуацию.
person
Anton Strogonoff
schedule
18.12.2010