Open In App

How to Efficiently Delete a Record in Django

Last Updated : 15 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In Django, deleting a record (or row) from a database table associated with a model is straightforward. Django models provide a delete() method that can be called on an individual object, or on a QuerySet of objects to remove them from the database. Deleting records is a fundamental operation, often needed when data becomes outdated, incorrect, or irrelevant.

In this article, we'll focus on deleting records efficiently from the database using Django models.

Deleting Records Using the Django Admin Interface

Django provides an admin interface where we can easily delete records from the database without writing any code.

  • Step 1: Log in to the Django admin interface.
  • Step 2: Navigate to the model we want to delete a record from.
  • Step 3: Select the record(s) we wish to delete by checking the box beside them.
  • Step 4: At the top of the page, select the action Delete selected records from the dropdown and click the "Go" button.
  • Step 5: Confirm the deletion on the next page.

Once confirmed, the record is permanently removed from the database.

Using Django ORM

Here's how we can use Django Shell to run ORM queries to delete records:

1. Deleting Single Record

Step 1 - Retrieve the Record: We can user the Django model’s get() method to fetch the record we want to delete. This method requires a unique identifier or filter criteria.

Python
from myapp.models import Product

# Retrieve a record with a specific ID
record = Product.objects.get(id=1)

Step 2 - Delete the Record: Once we have the instance, we can call the delete() method to remove it from the database.

Python
record.delete()

This action will remove the record from the database permanently. Be cautious when using this method, as it will not ask for confirmation before deletion.

The get method can result in error if a Product with id=1 does not exists in the database. To avoid such errors, we can wrap the ORM queries in the try-except block.

Python
from myapp.models import Product

# Retrieve a specific record
try:
    record = Product.objects.get(id=1)
    # Delete the record
    record.delete()
    print("Record deleted successfully")
except Product.DoesNotExist:
    print("Record not found")

Explanation:

  • get() Method: It returns a single record for the given parameters otherwise raises a DoesNotExist exception.
  • delete() Method: It permanently removes the record from the database.

2. Deleting Multiple Records

To delete more than one record with some filter criteria, we can use filter() to get a queryset, and then call delete() on the queryset. This is an efficient way for bulk deletions.

Python
from myapp.models import Product

# Delete records that match specific criteria
deleted_count, _ = Product.objects.filter(is_expired=True).delete()
print(f"{deleted_count} records deleted")

Explanation:

  • filter() Method: Returns a queryset containing records matching the given criteria.
  • delete() Method: If this method is called on a queryset object then all records in that queryset are deleted.

3. Deleting All Records

We can delete all records by fetching all records using all() method which returns a queryset then call delete() method.

Python
from myapp.models import Product

# Delete all records in model
deleted_count, _ = Product.objects.all().delete()
print(f"All records deleted. {deleted_count} records were removed.")

Explanation:

  • all() Method: Returns all records in the table.
  • delete() Method: Deletes all records in the queryset.

4. Handling Cascade on Foreign Keys

When deleting records, especially those linked by foreign keys, it is important to manage the related data. Django provides three options for handling deletions when foreign keys are involved:

  • CASCADE: Automatically delete related records. If we delete a parent object, all child objects are also deleted.
  • PROTECT: Prevent deletion of the parent object if it has related child objects.
  • SET_NULL: Set the foreign key field to NULL in the related objects.
  • RESTRICT: Similar to ‘PROTECT', but raises a more specific ProtectedError exception
  • SET_DEFAULT: Similar to ‘SET_NULL', but the foreign key will be set to its default value instead of NULL.
  • SET(): Specify a callable (usually a function) that will be called to set the value of the foreign key when the referenced object is deleted.
  • DO_NOTHING: Doesn’t perform any action when the referenced object is deleted

To learn more about these read: Foreign Keys On_Delete Option in Django Models

Let's say we have these models in our Django app:

Python
from django.db import models

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

class ChildModel(models.Model):
    parent = models.ForeignKey(ParentModel, on_delete=models.CASCADE)
    description = models.TextField()

Here, on_delete=models.CASCADE: If a ParentModel instance is deleted, all the associated instances with ChildModel will be deleted automatically.

For Example:

>>> from myapp.models import ParentModel, ChildModel
>>> parent = ParentModel.objects.create(name="Parent Object")
>>> child1 = ChildModel.objects.create(parent=parent, description="Child 1")
>>> child1 = ChildModel.objects.create(parent=parent, description="Child 2")
>>>
>>> parent.delete()
(3, {'myapp.ChildModel': 2, 'myapp.ParentModel': 1})
>>>

The output says that three records were delete, one instance of ParentModel and two Instances of ChildModel.

5. Deleting objects with Many-to-Many Relationship

In a many-to-many relationship, both models can have multiple related records. Django handles the relationship with an intermediary table behind the scenes.

Example Models:

Python
from django.db import models

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

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author, related_name="books")

    def __str__(self):
        return self.title

When we delete an Author or a Book, Django removes the entry in the intermediary table, severing the relationship without deleting the related objects unless explicitly handled.

Python
book = Book.objects.get(id=1)
book.delete()  # Deletes the book and removes its relationships with any authors

author = Author.objects.get(id=1)
author.delete()  # Deletes the author and removes its relationships with any books

Example:

>>> from myapp.models import Author, Book     
>>> author = Author.objects.first()
>>> author.books.all()
<QuerySet [<Book: Book Two>, <Book: Book One>]>
>>>
>>> author.delete()
(3, {'myapp.Book_authors': 2, 'myapp.Author': 1})
>>>

Here, the author was related to two books.

How deletion works?

When working with Django models, the on_delete argument in a ForeignKey or OneToOneField defines how the database should behave when the related object (usually the "parent" or referenced model) is deleted. Here’s a breakdown of each of the common on_delete options with model definitions and example queries.

1. When on_delete=models.CASCADE

Behavior:

When the parent object is deleted, all related objects (child objects) are also deleted. This is useful for tightly coupled data where deleting a parent should automatically clean up its children.

Example:

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

In this case, if we delete an Author, all related Book records will also be deleted.

Python
# Deleting an author
author = Author.objects.get(id=1)

# All books written by this author will also be deleted.
author.delete()

2. When on_delete=models.PROTECT

Behavior: Prevents deletion of the parent object if there are any related objects. This ensures that the relationship stays intact and prevents data loss.

Example:

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.PROTECT)

In this case, if we attempt to delete an Author that has related Book records, a ProtectedError will be raised, preventing the deletion.

Python
# Trying to delete an author with books
author = Author.objects.get(id=1)

# Raises django.db.models.ProtectedError
author.delete()

3. When on_delete=models.RESTRICT

Behavior: Prevents deletion of the parent object if there are related objects, but provides a more customizable restriction than PROTECT. It allows control over what happens when an object is prevented from deletion.

Example:

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.RESTRICT)

Similar to PROTECT, this prevents deletion of the Author if related Book records exist, but we have more options to handle the error.

Python
# Attempt to delete an author
author = Author.objects.get(id=1)

# Raises a django.db.models.RestrictedError if books exist
author.delete()

4. When on_delete=models.SET_NULL

Behavior: When the parent object is deleted, the related object’s foreign key is set to NULL, allowing the child to exist without the parent. This requires the foreign key field to have null=True.

Example:

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)

When an Author is deleted, the author field of the related Book records will be set to NULL.

Python
# Deleting an author
author = Author.objects.get(id=1)

# Books remain, but their 'author' field is set to NULL
author.delete()  

5. When on_delete=models.SET_DEFAULT

Behavior: When the parent object is deleted, the related object’s foreign key is set to a default value. The field must have a default value specified.

Example:

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.SET_DEFAULT, default=1)

When an Author is deleted, the author field of the related Book records will be set to the default value (in this case, the author with ID 1).

Python
# Deleting an author
author = Author.objects.get(id=2)

# Books' 'author' field is set to default (ID = 1)
author.delete()

6. When on_delete=models.SET()

Behavior: When the parent object is deleted, the related object’s foreign key is set to a value specified by a callable. The callable function defines the value that the foreign key will be set to upon deletion.

Example:

Python
def get_default_author():
    return Author.objects.get(name="Anonymous")

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.SET(get_default_author))

In this case, when an Author is deleted, the author field of the related Book records will be set to the result of the get_default_author() function (e.g., "Anonymous").

Python
# Deleting an author
author = Author.objects.get(id=3)

# Books' 'author' field is set to the value returned by `get_default_author()`
author.delete()

7. When on_delete=models.DO_NOTHING

Behavior: Django will do nothing with the related objects when the parent is deleted. This means we must manually handle what happens to the related records, or we may end up with broken references in the database.

Example:

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

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, on_delete=models.DO_NOTHING)

When an Author is deleted, nothing happens to the related Book records, which could lead to database integrity issues if not handled manually.

Python
# Deleting an author
author = Author.objects.get(id=4)
author.delete()  # Books will still reference the deleted author, potentially causing errors

Conclusion

Record deletion within Django models is pretty easy with the powerful ORM system that Django provides. Be it the deletion of a single record, removal of multiple records on certain criteria, or even complex relationships like cascade deletions, Django's ORM allows many ways to do this efficiently. It gets even better: from using the get() method for deleting items one by one, using filter() for bulk actions, and even using cascade options for associated records, Django keeps the management of records in the database intuitive and fast. Moreover, soft deletes can be implemented for those cases when recovery or auditing of data needs to be performed. Understanding and taking advantage of these deletion methods will help us keep data clean and accurate in our Django applications while supporting a wide variety of data management scenarios.


Next Article
Article Tags :
Practice Tags :

Similar Reads