Skip to content

Instantly share code, notes, and snippets.

@josemarimanio
Last active September 11, 2020 01:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save josemarimanio/4409dc84776e650c401159c43b9d10a3 to your computer and use it in GitHub Desktop.
Save josemarimanio/4409dc84776e650c401159c43b9d10a3 to your computer and use it in GitHub Desktop.
Django: Cascade deletion to related one-to-one fields

Django: Cascade deletion to related one-to-one fields

This gist assumes that an app named base exists and is included in INSTALLED_APPS via base.apps.BaseConfig.

base.utils.delete_related_onetoonefield works by looping thru the model instance's available fields and deleting all non-null django.db.models.fields.related.OneToOneField instances.

from django.apps import AppConfig
class BaseConfig(AppConfig):
name = 'base'
verbose_name = 'Base'
def ready(self):
import base.signals # noqa
from django.db import models
class OneToOneRequiredModel(models.Model):
value = models.CharField(max_length=255)
class OneToOneOptionalModel(models.Model):
value = models.CharField(max_length=255)
class BaseModel(models.Model):
one_to_one_required = models.OneToOneField(OneToOneRequiredModel, on_delete=models.SET_CASCADE)
one_to_one_optional = models.OneToOneField(OneToOneOptionalModel, null=True, blank=True, on_delete=models.SET_NULL)
from base.models import BaseModel
from base.utils import delete_related_onetoonefield
@receiver(pre_delete, sender=Application)
def delete_base_cascade_onetoonefields(sender, instance, using, **kwargs):
"""
Cascade 'BaseModel' model deletion to OneToOneField fields
"""
delete_related_onetoonefield(instance)
from django.db.models.fields.related import OneToOneField
def delete_related_onetoonefield(instance):
"""
Helper function to cascade deletion to related.OneToOneField fields from a model instance
"""
for field in type(instance)._meta.get_fields():
if isinstance(field, OneToOneField):
try:
getattr(instance, field.name).delete()
except AttributeError:
# Field is of null value
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment