shahab
shahab

Reputation: 323

overrided delete() method not working on all part of django admin

I have two tables in my Django model, Category and Image.

when I create a Category, an Image creates automatically, and when a Category deletes, The corresponding Image will be destroyed.

I override the delete() method in Category. It works correctly when I click delete button in the details page of the object (It removes corresponding Image objece):

detail page

But when I want to delete the Category object in the listed objects page:

enter image description here

enter image description here

It doesn't remove the corresponding Image object.

How can I fix this and delete every Category I selected and so that it removes every corresponding Image Objects?

My models.py is like:

from django.db.models import Q


class Image(models.Model):
    image_id = models.IntegerField(unique=True, null=True)
    image = models.FileField(upload_to='all/', null=True, blank=True)

    def __str__(self):
        return '%s | %s' % (self.image_id, self.image)

class Category(models.Model):
    category_id = models.IntegerField(primary_key=True, unique=True, editable=False)
    title = models.CharField(max_length=50, null=False, blank=False)
    c_thumbnail = models.FileField(upload_to='img/thumbnailCategory/', null=False, blank=False)

    def delete(self, **kwargs):
        image = Image.objects.get(Q(image_id=self.category_id))
        image.delete()
        super(Category, self).delete()

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        super(Category, self).save(force_insert, force_update, *args, **kwargs)
        # this will create or update an Image
        Image.objects.update_or_create(image_id=self.category_id, image=self.c_thumbnail)
        super(Category, self).save(force_insert, force_update, *args, **kwargs)

    def __str__(self):
        return '%s | %s' % (self.title, self.category_id)

Thanks in advance.

Upvotes: 1

Views: 897

Answers (1)

Benjamin Hicks
Benjamin Hicks

Reputation: 764

You will need to use signals to do this in your current database model. The issue comes with the way queryset deletes work, which the documentation explains here. When you delete a category using the list view, it does a queryset delete, which does NOT trigger the model's delete.

As you have things set up now, you can instead listen for the post_delete (or pre_delete) signal for Category. See the documentation on signals here

All that said, there is an easier way to what you want:

make image_id into something meaningful like category and set it up as

category = models.ForeignKey('Category', on_delete=models.CASCADE)

Then when you delete a Category object, it will also remove images with a foreign key relationship set to that Category. Much cleaner.

Upvotes: 4

Related Questions