Метод delete

Метод delete применяется к объекту модели или к QuerySet и удаляет соответствующие записи из базы данных. При вызове на отдельном объекте удаляется одна запись, при вызове на QuerySet удаляются все записи, входящие в набор. Метод возвращает количество удаленных объектов и словарь с количеством удаленных объектов по типам моделей.

Синтаксис

python# Удаление отдельного объекта
instance.delete()

# Удаление всех объектов в QuerySet
QuerySet.delete()

Пример . Удаление одного объекта

Давайте удалим статью с идентификатором 1 из базы данных:

pythonfrom myapp.models import Article

# Получаем статью
article = Article.objects.get(id=1)

# Удаляем статью
res = article.delete()

print(f"Deleted: {res}")

Результат выполнения кода:

python"Deleted: (1, {'myapp.Article': 1})"

Метод возвращает кортеж, где первое значение - количество удаленных объектов, а второе - словарь с количеством удаленных объектов по каждой модели.

Пример . Массовое удаление

Давайте удалим все статьи со статусом 'draft':

pythonfrom myapp.models import Article

# Фильтруем статьи для удаления
draft_articles = Article.objects.filter(status='draft')

# Удаляем все отфильтрованные статьи
res = draft_articles.delete()

print(f"Deleted {res[0]} articles")

Результат выполнения кода:

python"Deleted 5 articles"

Удаление с каскадным эффектом

При удалении объекта, на который ссылаются другие модели через внешний ключ, происходит каскадное удаление связанных объектов. Рассмотрим это на примере моделей:

pythonfrom django.db import models

class Category(models.Model):
  name = models.CharField(max_length=100)

class Article(models.Model):
  title = models.CharField(max_length=200)
  category = models.ForeignKey(Category, on_delete=models.CASCADE)

Теперь удалим категорию и посмотрим, что произойдет со связанными статьями:

pythonfrom myapp.models import Category, Article

# Получаем категорию
category = Category.objects.get(name='Technology')

# Удаляем категорию (каскадно удалятся все статьи)
res = category.delete()

print(f"Deleted: {res}")

Результат выполнения кода:

python"Deleted: (3, {'myapp.Article': 2, 'myapp.Category': 1})"

Как видим, вместе с категорией удалились и все связанные статьи.

Особенности работы с QuerySet

Важно помнить, что метод delete на QuerySet выполняется непосредственно в базе данных без загрузки объектов в память. Это делает массовое удаление очень быстрым, но при этом сигналы pre_delete и post_delete не отправляются для каждого объекта:

pythonfrom myapp.models import Article

# Быстрое массовое удаление
res = Article.objects.filter(created_at__year=2020).delete()

print(f"Deleted {res[0]} old articles")

Результат выполнения кода:

python"Deleted 15 old articles"

Смотрите также

  • метод delete для QuerySet,
    который удаляет все объекты из QuerySet
  • метод save,
    который сохраняет объект в базу данных
  • метод pre_delete,
    сигнал, отправляемый перед удалением объекта
  • метод post_delete,
    сигнал, отправляемый после удаления объекта