Django Delete Data

Deleting data in Django is done with instance.delete() for a single row, or by calling delete() on a filtered queryset to remove many rows in one statement.

Deleting a Single Instance

Fetch the instance you want to remove, then call its delete() method. It returns a tuple: the total number of objects deleted, and a dictionary breaking that count down per model.

Example

from .models import Product

product = Product.objects.get(pk=7)
result = product.delete()
print(result)  # (1, {'shop.Product': 1})

Deleting a QuerySet

Calling delete() on a filtered queryset removes every matching row in a single query. Be careful - calling it on an unfiltered queryset removes the entire table's contents.

Example

# Remove every product that's been out of stock since before the cutoff
Product.objects.filter(in_stock=False, created_at__lt=cutoff_date).delete()

on_delete and Related Rows

When a row is deleted and other rows point to it through a ForeignKey, the on_delete argument decides what happens to those related rows.

  • CASCADE - delete the related rows too (e.g. delete a Product's Reviews along with it)
  • PROTECT - block the delete and raise ProtectedError if related rows exist
  • SET_NULL - set the foreign key to NULL (the field must allow null=True)
  • SET_DEFAULT - set the foreign key to its default value
  • DO_NOTHING - leave it to the database, rarely what you want
on_delete OptionBehavior When the Related Row Is Deleted
CASCADEDeletes this row too
PROTECTRaises ProtectedError, blocking the delete
SET_NULLSets the foreign key column to NULL
SET_DEFAULTSets the foreign key to its default value
DO_NOTHINGNo automatic action; can leave a dangling reference
Note: delete() on both an instance and a queryset returns a tuple: the total number of objects deleted, and a dictionary breaking that count down per model - including anything removed through CASCADE.
Note: Product.objects.all().delete() removes every row in the table with no confirmation prompt. Always double-check your filter() conditions - and consider testing them with a matching .count() first - before calling delete().

Exercise: Django Delete Data

Which method removes a specific model instance's row from the database?