7👍
It depends on your business requirements. Should every Item
always point to a valid Policy
? And what’s the requirement from business point-of-view when a Policy
gets deleted? Should the Item
s pointing to it also be deleted? We don’t know your requirements, so it’s difficult to answer your question. These are your options from a technical perspective:
- Set
on_delete=CASCADE
if you want theItem
to be deleted when thePolicy
is deleted - Set
on_delete=PROTECT
if you don’t want to allow anyPolicy
to be deleted if there’s still anyItem
pointing to it. In that case you’ll have totry: policy.delete(); except ProtectedError: ...
in your code to handle that situation. - Set
on_delete=SET_DEFAULT
if you know your default policy will not be deleted (you could override thedelete
method onPolicy
to avoid deleting the default policy). - Set
on_delete=SET_NULL
if anItem
can have noPolicy
. That may be valid in certain business scenarios. But in this case you must also havenull=True
.
1👍
I reproduced your scenario with Django 4.1
and sqlite
, and I got the exception you waited for!
But just to provide more customizability, especially in handling exceptions, the following code works with the mentioned environment:
from django.db import models
import django.db
def SET_DEFAULT_AND_PREVENT_DELETE_DEFAULT(collector, field, sub_objs, using):
"""
``sub_objs`` is the Queryset of Items that are affected by this delete.
Hence, none of them should have referenced the default Policy (Otherwise,
the default Policy is going to be deleted!).
Also, if we are deleting an Item, there should be a default Policy to
be set as the new Policy of Item.
"""
try:
default_policy = Policy.objects.get(name='default')
except Policy.DoesNotExist:
raise django.db.InternalError("You should have default policy before "
"deleting a referenced policy")
for item in sub_objs:
if item.policy == default_policy:
raise django.db.InternalError("You cannot delete default policy "
"when there are items referencing it")
collector.add_field_update(field, default_policy, sub_objs)
class Policy(models.Model):
name = models.SlugField(max_length=256, blank=False, unique=True)
class Item(models.Model):
policy = models.ForeignKey('Policy', on_delete=SET_DEFAULT_AND_PREVENT_DELETE_DEFAULT)
- [Django]-Django Serializer returns JSON for parent class objects only and leave child objects as same?
- [Django]-How to import a template tag in the interactive shell?
- [Django]-Passing Editable Fields as validated_data method of Django-Rest-Framework Serializer
- [Django]-Django cache_page – prepopulate/pre-cache
Source:stackexchange.com