In the following, I have a Post
model. A Post
object has a status
field that can be 'unpublished'
or 'published'
.
if status is 'published'
, I'd like to prevent the object from being deleted, and would like to keep this logic encapsulated in the model itself.
from model_utils import Choices # from Django-Model-Utils
from model_utils.fields import StatusField
class Post(model.Models)
STATUS = Choices(
('unpublished', _('Unpublished')),
('published', _('Published')),
)
...
status = StatusField(default=STATUS.unpublished)
How can I do this? Overriding the delete
method won't work if the objects are being deleted in bulk with a QuerySet
. I've read not to use receivers, but I'm not sure why.
This is what I have following @Todor's comment:
In signals.py
:
from django.db.models import ProtectedError
from django.db.models.signals import pre_delete
from django.dispatch import receiver
from .models import Post
@receiver(pre_delete, sender=Post, dispatch_uid='post_pre_delete_signal')
def protect_posts(sender, instance, using, **kwargs):
if instance.status is 'unpublished':
pass
else: # Any other status types I add later will also be protected
raise ProtectedError('Only unpublished posts can be deleted.')
I welcome improvements or better answers!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With