user5505017
user5505017

Reputation: 21

Django - .delete() method is called, but instance remains in DB

got a little problem here using the Django-framework and its .delete() method. Im using the following model

class Message(models.Model):
  ...
  sender = models.ForeignKey(User, related_name="%(class)s_sender")
  user = models.ManyToManyField(User, related_name="%(class)s_recip")
  trash = models.ManyToManyField(User, related_name="%(class)s_trash", blank=True)
  ...

So my aim is to check if both M2M fields "user" and "trash" do not contain objects/keys anymore, and if so, the corresponding Message instance should be deleted from the database. To archieve this I'm using m2m_changed signals as follows

def set_recip_names(sender, instance, action,**kwargs):
    print instance
    if action == "post_remove":
        if instance.user.all().count() == 0 and instance.trash.all().count() == 0:
            print instance.id
            instance.delete()

def msg_del(sender, **kwargs):
    print "Message deleted"

m2m_changed.connect(set_recip_names, sender=Message.user.through)
m2m_changed.connect(set_recip_names, sender=Message.trash.through)
post_delete.connect(msg_del, sender=Message)

The first two print statements are for debug purpous of course, and both print exactly what Im expecting: instance IS the corresponding instance to be deleted, and instance.id confirms this, as well as telling me that Django actually will execute the .delete() method.

The second post_delete signal is for debugging purpous too, and it is called as expected, so Im getting the output "Message deleted".

So the big problem is, that the "to-be-deleted" instance remains in the database. Ive searched the internet for an hour now but I dont see anything is wrong with my code.

Any suggestions are welcomed, or if you know any better way to do what Im trying to do, please let me know.

Solved Problem was actually pretty obvious. One of my code snippets, where on user interaction elements from my M2M fields are removed looks like

...
    try:
        message = Message.objects.get(id=msg)

        if usr not in message.trash.all():
            continue
        if usr != message.sender:
            message.user.remove(usr) # m2m_changed triggered

        message.trash.remove(usr) # m2m_changed triggered

        # if instance was removed by now, this .save() will
        # insert the python-local object in the db, so it looked
        # like the same instance is still there, but I saw that
        # the "old" instance suddenly had a new id

        message.save()

    except Message.DoesNotExist:
        continue
...

Upvotes: 2

Views: 1941

Answers (1)

Vingtoft
Vingtoft

Reputation: 14616

You can delete the record directly by doing this:

YourModel.objects.get(id=instance.id).delete()

If the record exists, then it will be deleted in the database.

Your instance is saved in the RAM and may not be deleted, you can do that manually by deleting it from the RAM: del instance

Upvotes: 1

Related Questions