Метод delete
Метод delete применяется к объекту модели или к QuerySet и удаляет соответствующие записи из базы данных. При вызове на отдельном объекте удаляется одна запись, при вызове на QuerySet удаляются все записи, входящие в набор. Метод возвращает количество удаленных объектов и словарь с количеством удаленных объектов по типам моделей.
Синтаксис
# Удаление отдельного объекта
instance.delete()
# Удаление всех объектов в QuerySet
QuerySet.delete()
Пример . Удаление одного объекта
Давайте удалим статью с идентификатором 1 из базы данных:
from myapp.models import Article
# Получаем статью
article = Article.objects.get(id=1)
# Удаляем статью
res = article.delete()
print(f"Deleted: {res}")
Результат выполнения кода:
"Deleted: (1, {'myapp.Article': 1})"
Метод возвращает кортеж, где первое значение - количество удаленных объектов, а второе - словарь с количеством удаленных объектов по каждой модели.
Пример . Массовое удаление
Давайте удалим все статьи со статусом 'draft':
from myapp.models import Article
# Фильтруем статьи для удаления
draft_articles = Article.objects.filter(status='draft')
# Удаляем все отфильтрованные статьи
res = draft_articles.delete()
print(f"Deleted {res[0]} articles")
Результат выполнения кода:
"Deleted 5 articles"
Удаление с каскадным эффектом
При удалении объекта, на который ссылаются другие модели через внешний ключ, происходит каскадное удаление связанных объектов. Рассмотрим это на примере моделей:
from 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)
Теперь удалим категорию и посмотрим, что произойдет со связанными статьями:
from myapp.models import Category, Article
# Получаем категорию
category = Category.objects.get(name='Technology')
# Удаляем категорию (каскадно удалятся все статьи)
res = category.delete()
print(f"Deleted: {res}")
Результат выполнения кода:
"Deleted: (3, {'myapp.Article': 2, 'myapp.Category': 1})"
Как видим, вместе с категорией удалились и все связанные статьи.
Особенности работы с QuerySet
Важно помнить, что метод delete на QuerySet выполняется непосредственно в базе данных без загрузки объектов в память. Это делает массовое удаление очень быстрым, но при этом сигналы pre_delete и post_delete не отправляются для каждого объекта:
from myapp.models import Article
# Быстрое массовое удаление
res = Article.objects.filter(created_at__year=2020).delete()
print(f"Deleted {res[0]} old articles")
Результат выполнения кода:
"Deleted 15 old articles"
Смотрите также
-
метод
deleteдляQuerySet,
который удаляет все объекты изQuerySet -
метод
save,
который сохраняет объект в базу данных -
метод
pre_delete,
сигнал, отправляемый перед удалением объекта -
метод
post_delete,
сигнал, отправляемый после удаления объекта