Django и мягкое удаление: архитектура реализации

Определения

  • SOFT DELETE - не удаляет объект из базы данных, но делает это
  • HARD DELETE — полностью удаляет объект из базы данных

Вопрос

Как лучше всего реализовать мягкое удаление в кодовой базе (в частности, в проекте Django)?

Я думаю, что самым простым способом было бы просто добавить:

is_deleted = models.BooleanField(default=False)

в суперкласс, который реализует softDeleteObject, а затем переопределить delete(), чтобы установить соответствующие флаги для рассматриваемых объектов. Связанные объекты также должны наследоваться от одного и того же суперкласса.

Вместо этого вместо этого можно было бы удалить оригинал и получить то, что составляет объект архива, который является представлением удаленных объектов.

Анализ

Первый кажется более простым, но требует некоторых широких переопределений — например, User нужно было бы переопределить, чтобы гарантировать, что отношения внешнего ключа всех удаленных объектов все еще сохраняются, и что удаление пользователя затем не не удалить все их мягко удаленные объекты.

Второй может быть реализован с помощью сигналов pre_delete, запускающих создание суррогатных объектов. Это снова имеет некоторые преимущества (не нужно переопределять все delete() методы), но требует реализации архивных версий моделей, используемых в проекте.

Что предпочтительнее и есть ли другие альтернативы?


person jvc26    schedule 19.02.2013    source источник


Ответы (1)


Почему бы не использовать активные/удаленные/статусные флаги на конкретных моделях, где это необходимо, и сделать это именно так? Или загляните в приложение django-reversion, возможно, там есть все, что вам нужно ;)

person Bruce    schedule 19.02.2013
comment
Что ж, это вариант 1, как и в вопросе, однако, например, он требует переопределения User, поскольку метод delete() не должен удалять пользователей, иначе он повредит все нижестоящие отношения FKey. Это, безусловно, возможность, но мне было интересно, есть ли другие/лучшие идеи... - person jvc26; 19.02.2013
comment
@ jvc26 это зависит от вашего использования. django-reversion реализовал второй вариант, вы можете взглянуть на него. Я использую свою реализацию варианта 2 для архивирования удаленных объектов, таких как пользователи спама, и чувствую себя счастливым: нет необходимости переписывать менеджер или заботиться о администраторе Django о том, отображать ли удаленные объекты, просто покажите их в списке изменений другой модели. с примечаниями, описывающими причины удаления и их __unicode__(). - person okm; 19.02.2013
comment
Я думаю, что нет общего правила, как это сделать, но это зависит от конкретной ситуации. Удаление/отключение пользователей может быть довольно сложным. Если вы удаляете пользователя, вы должны решить, что делать со связанными объектами (удалить или сопоставить с каким-то подготовленным пользователем, например, с удаленным пользователем). Для других моделей, таких как Projects, вы можете использовать завершенный флаг и не показывать его в списке по умолчанию. Обычно вы не хотите удалять какие-либо данные. - person Bruce; 19.02.2013
comment
Спасибо за вклад, @Bruce, относительно удаления пользователей и повторного назначения объектов их собственности, как бы вы это сделали? Проблема, конечно, в отключении пользователей, другие флаги/архивные версии довольно просты... - person jvc26; 19.02.2013
comment
Я думаю, что это более сложная тема, которую я могу описать в нескольких словах. Отключите учетную запись пользователя, а затем решите, что делать с каждым из связанных данных. Например, когда у вас есть обсуждение, которое начал пользователь, вы можете потерять много важного контента, если удалите его. Если вы сделаете, например, {% if user.active %}{{ user.get_full_name }}{% else %}Anonymous{% endif %} или установите для пользователя какую-либо анонимную учетную запись, вы все равно можете иметь некоторые ссылки на реальную учетную запись пользователя. имя в обсуждениях (например, я не согласен с тем, что написал Билли Джо...). В таких случаях напишите хорошие условия обслуживания :) - person Bruce; 25.02.2013