About Ensuring That No Objects Get Deleted by Accident
If you blindly set on_delete=models.CASCADE
for foreign keys and then programmatically delete the parent object at some point, all children will be deleted too whether that's wanted or not.
You can check the related objects to be deleted before deletion using this utility function:
def get_cascade_deletion_objects(instance):
"""
Returns all objects that would be deleted if this instance was deleted.
"""
from django.db.models.deletion import Collector
from django.db import router
using = router.db_for_write(instance.__class__, instance=instance)
collector = Collector(using=using)
collector.collect([instance])
# Get all objects grouped by model
objects_to_be_deleted = collector.data
# Count objects by model
deletion_summary = {}
for model, instances in objects_to_be_deleted.items():
model_name = f"{model._meta.app_label}.{model._meta.model_name}"
deletion_summary[model_name] = len(instances)
return {
"detailed": objects_to_be_deleted, # Full object list grouped by model
"summary": deletion_summary, # Count by model type
"total_count": sum(deletion_summary.values()), # Total count of objects
}
Then it would work like this:
>>> category = Category.objects.get(slug="dummy")
>>> info = get_cascade_deletion_objects(category)
>>> info
{
"detailed": defaultdict(<class 'set'>, {
<class 'categories.models.Category'>: { <Category: Dummy> },
<class 'posts.models.Post'>: { <Post: Hello World>, <Post: Bye Bye> },
}),
"summary": {"categories.category": 1, "posts.post": 2},
"total_count": 3,
}
By inspecting the objects to be deleted together, you can take an explicit action like attaching another category or skipping the deletion of the parent object.
Tips and Tricks Programming Development Django 5.2 Django 4.2 Django 3.2
Also by me
Django Paddle Subscriptions app
For Django-based SaaS projects.
Django GDPR Cookie Consent app
For Django websites that use cookies.