Reputation: 1370
I'm currently working on a Django blog app where I have a Post
connecting to a Category
. The Category
has both name
and times_used
fields. times_used
will be incremented by 1 after a Post is created and I have achieved this overriding the save()
method on the Post
model. I'm trying to override the delete()
method to decrement the current post's category by 1 but it's not actually reaching the overridden delete()
method it seems, because the category still has the incremented value even after the post got deleted. See my code below...
model.py
class Category(models.Model):
name = models.CharField(max_length=150, unique=True)
times_used = models.IntegerField(default=0)
class Post(models.Model):
category = models.ForeignKey(Category, on_delete=models.CASCADE)
# This increments this category by 1 then saves the post - Works well!
def save(self, *args, **kwargs):
self.category.times_used += 1
self.category.save()
super(Post, self).save(*args, **kwargs)
# This decrements this category by 1 then deletes the post - Which is not working...
def delete(self, *args, **kwargs):
self.category.times_used -= 1
self.category.save()
super(Post, self).delete(*args, **kwargs)
Any suggestions how to accomplish this?
Upvotes: 1
Views: 3238
Reputation: 1370
I read about Django signals just now and have accomplished what I wanted to. According to the Django documentation... the delete() method doesn't get called when we override it to delete objects in bulk using a QuerySet. So it's best to use a signal to get these types of job done.
In my models.py
I've pass the Post
as an argument to a function which I have a created in signals.py
models.py
class Post(models.Model):
....
delete_post_signal(Post)
Within my signals.py
I have the following code...
from django.dispatch import receiver
from django.db.models.signals import pre_delete
def delete_post_signal(Post):
@receiver(pre_delete, sender=Post)
def decrement_category_usage(sender, instance, **kwargs):
instance.category.times_used -= 1
instance.category.save()
This worked for me perfectly...
Upvotes: 3
Reputation: 163
You can do it with pre_delete signal like this
@receiver(pre_delete, sender=Post)
def my_handler(sender, instance, **kwargs):
instance.category.times_used -= 1
instance.category.save()
Upvotes: 0