Подтвердить что ты не робот

Как я могу легко пометить записи как удаленные в моделях Django, а не удалять их вообще?

Вместо того, чтобы удалять записи в моем приложении Django, я хочу просто отметить их как "удаленные" и скрывать их от активных запросов. Моя основная причина заключается в том, чтобы предоставить пользователю опцию восстановления, если они случайно удалили запись (эти записи также могут потребоваться для отслеживания отслеживания бэкэнд).

Существует много отношений с внешними ключами, поэтому, когда я помечаю запись как удаленную, мне придется "каскадировать" этот флаг удаления для этих записей. Какие инструменты, существующие проекты или методы следует использовать для этого?

4b9b3361

Ответ 1

Django предлагает изящный механизм, который вы ищете.

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

Подробнее см. здесь: http://docs.djangoproject.com/en/dev/topics/db/managers/#using-managers-for-related-object-access

Ответ 2

Хороший вопрос, мне было интересно, как эффективно это делать самому.

Я не уверен, что это сделает трюк, но django-reversion, похоже, делает то, что вы хотите, хотя вы, вероятно, захотите изучите, как он достигает этой цели, поскольку есть некоторые неэффективные способы сделать это.

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

Я добавлю, что по большей части я не рассматриваю ни одно из этих решений, стоящее за хлопот; Я обычно просто сосать его и фильтровать мои запросы по логическому знаку. Это позволяет избежать многих проблем, которые могут возникнуть, если вы попытаетесь стать слишком умными. Конечно, это боль и не очень СУХОЙ. Разумным решением было бы сочетание пользовательского менеджера, осознавая его ограничения, если вы попытаетесь найти с ним соответствующую модель.

Ответ 3

Я думаю, что использование логического "is_active" флага в порядке - вам не нужно каскадировать флаг на соответствующие записи на уровне db, вам просто нужно продолжать ссылаться на статус родителя. Это то, что происходит с моделью пользователя contrib.auth, помните, что пометка пользователя как not is_active не подсказывает django проходить через связанные модели и магически пытается деактивировать записи, а вы просто продолжаете проверять is_active атрибут пользователя, соответствующий связанный предмет.

Например, если у каждого пользователя много закладок, и вы не хотите, чтобы неактивные пользовательские закладки были видимыми, просто убедитесь, что bookmark.user.is_active является истинным. Вряд ли понадобится флаг is_active в самой закладке.

Ответ 4

Вот небольшой учебник по блогам от Грега Аллара из пары лет назад, но я реализовал его с помощью Django 1.3, и это было здорово. Я добавил методы к моим объектам с именем soft_delete, undelete и hard_delete, которые устанавливают self.deleted = True, self.deleted = False и возвращают self.delete() соответственно.

Диспетчер моделей Django для мягкого удаления записей и как настроить Django Admin

Ответ 5

Существует несколько пакетов, которые предоставляют эту функциональность: https://www.djangopackages.com/grids/g/deletion/

Я разрабатываю один https://github.com/meteozond/django-permanent/ Он заменяет методы удаления по умолчанию Manager и QuerySet, чтобы привести к логическому удалению. Он полностью затеняет методы удаления Django по умолчанию с одним исключением - маркирует модели, которые наследуются от PermanentModel вместо удаления, даже если их удаление вызвано отношением.