Найти в Дзене
Электрообзор

"Мягкое удаление" в Django

Для реализации мягкого удаления в Django требуются три основных шага: Добавление поля is_deleted в модель. Использование Кастомного Менеджера (Custom Manager) для фильтрации удаленных объектов. Изменение логики удаления в ваших представлениях (views) или методах модели. 1. Добавление поля в модель Добавьте булево поле в вашу модель (например, Category), чтобы отслеживать ее статус. python # project/models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=100)
# ... другие поля ...
is_deleted = models.BooleanField(default=False) # Поле мягкого удаления
def __str__(self):
return f"{self.name}"
# После изменения модели не забудьте:
# python manage.py makemigrations
# python manage.py migrate Используйте код с осторожностью. 2. Использование Кастомного Менеджера (Custom Manager) Чтобы не писать постоянно Category.objects.filter(is_deleted=False) во всем вашем коде, создайте кастомный менеджер. Он будет автоматич
Оглавление

Для реализации мягкого удаления в Django требуются три основных шага:

  1. Добавление поля is_deleted в модель.
  2. Использование Кастомного Менеджера (Custom Manager) для фильтрации удаленных объектов.
  3. Изменение логики удаления в ваших представлениях (views) или методах модели.

1. Добавление поля в модель

Добавьте булево поле в вашу модель (например, Category), чтобы отслеживать ее статус.

python

# project/models.py
from django.db import models

class Category(models.Model):
name = models.CharField(max_length=100)
# ... другие поля ...

is_deleted = models.BooleanField(default=False)
# Поле мягкого удаления

def __str__(self):
return f"{self.name}"

# После изменения модели не забудьте:
# python manage.py makemigrations
# python manage.py migrate

Используйте код с осторожностью.

2. Использование Кастомного Менеджера (Custom Manager)

Чтобы не писать постоянно Category.objects.filter(is_deleted=False) во всем вашем коде, создайте кастомный менеджер. Он будет автоматически скрывать удаленные объекты при каждом стандартном запросе Category.objects.all().

python

# project/models.py
from django.db import models

# 1. Создаем менеджер, который выбирает только не удаленные объекты
class ActiveCategoryManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(is_deleted=False)

class Category(models.Model):
name = models.CharField(max_length=100)
is_deleted = models.BooleanField(default=False)

# 2. Переопределяем стандартный менеджер objects
objects = ActiveCategoryManager()

# 3. Добавляем менеджер all_objects, если когда-нибудь понадобятся и удаленные записи
all_objects = models.Manager()

def __str__(self):
return f"{self.name}"

# 4. Добавляем метод для "удаления" объекта
def delete(self, *args, **kwargs):
self.is_deleted = True
self.save()

# 5. Добавляем метод для восстановления объекта
def restore(self, *args, **kwargs):
self.is_deleted = False
self.save()

Используйте код с осторожностью.

3. Изменение логики в представлениях (Views)

Теперь, когда вы "удаляете" объект в своем коде, вы вызываете кастомный метод delete(), а не стандартный метод Django, который выполняет SQL-DELETE.

В вашем представлении удаления (DeleteView или функции):

Используйте мягкое удаление:

python

# views.py
def delete_category_view(request, pk):
category = get_object_or_404(Category, pk=pk)
if request.method == 'POST':
# Используем наш кастомный метод, который просто меняет is_deleted на True
category.delete()
return redirect('success_url')
# ...

Итог

  • Когда вы вызываете Category.objects.all(), вы видите только активные категории.
  • Когда вы вызываете category.delete(), поле is_deleted становится True, и объект скрывается из всех стандартных запросов, но остается в базе данных.