15

In my app I want to keep a track of all the questions that are being deleted. And so I have created a class(table) as such in my models file.

class Deleted(models.Model):
question = models.IntegerField(null=True, blank=True)#id of question being deleted
user = models.IntegerField(null=True, blank=True)#id of user deleting the question
dt = models.DateTimeField(null=True, blank=True)#time question is deleted

When a user tries to delete a question This delete function is called:

def delete_questions(request, user, questions):
  for q in questions:
        q.delete()

My doubt is how can i make a pre_delete signal of django to populate the new table I have created.

~newbie trying hefty task~ Thanks in advance:)

The Recruit
  • 803
  • 3
  • 9
  • 18
  • 2
    What exactly are you having trouble with? Have you read the documentation regarding signals? https://docs.djangoproject.com/en/dev/topics/signals/ – Josh Smeaton Dec 13 '12 at 10:26

1 Answers1

45

You start off by defining the receiver you want to use:

def log_deleted_question(sender, instance, using, **kwargs):
    d = Deleted()
    d.question = instance.id
    d.dt = datetime.datetime.now() # consider using auto_now=True in your Deleted definition
    # not sure how you'd get the user via a signal, 
    # since it can happen from a number of places (like the command line)
    d.save()

Then define your receiver decorator:

from django.db.models.signals import pre_delete
from django.dispatch import receiver

@receiver(pre_delete, sender=Question, dispatch_uid='question_delete_log')

Add it altogether:

from django.db.models.signals import pre_delete
from django.dispatch import receiver

@receiver(pre_delete, sender=Question, dispatch_uid='question_delete_signal')
def log_deleted_question(sender, instance, using, **kwargs):
    d = Deleted()
    d.question = instance.id
    d.dt = datetime.datetime.now() 
    d.save()

You can put this function in your models.py file, as you know it'll be loaded and connected up correctly.

The problem though, is that you don't get the user requesting the delete. Since a delete can be triggered from the django api (command line, shell, etc), which doesn't have a request associated with it. For this reason, you might want to avoid using signals if it's absolutely critical that you store the user along with the delete.

guettli
  • 25,042
  • 81
  • 346
  • 663
Josh Smeaton
  • 47,939
  • 24
  • 129
  • 164
  • Thank u for answering:) But @Josh the "class Deleted" I put is the table I newly created so that they cn be populated with the values, and I had trouble regarding that. What you said looks very good, tried that but it said could not import from django.core.signals import pre_delete so i tried importing as from django.db.models.signals import pre_delete. Then again it complained that could not import receiver.. Tried googling it but as suggested there,i cannot change or delete other versions of django.. any workarounds for that? and one doubt-for user id can we not get using (providing args) – The Recruit Dec 13 '12 at 11:57
  • Re: the specific user, I googled around hoping to get some answer and got around this http://stackoverflow.com/questions/6847952/django-determine-which-user-is-deleting-when-using-post-delete-signal.. trying to figure out how it fits my context :) – The Recruit Dec 13 '12 at 12:00
  • I m using Django 1.2 and so there was a problem reg. imprting reciever. I overcam that by using post_delete.connect(my_callback_func, sender=mymodel) However Im having trouble getting the user who deleted, could you bail me out :) – The Recruit Dec 14 '12 at 06:37
  • 1
    @TheRecruit, you can't determine the user that deleted the object in a signal; that info isn't available. – Mike Stoddart Jun 26 '17 at 17:56
  • 2
    @TheRecruit, you probably had an import loop. The models.py was importing the signals.py, which was importing the models.py.... I know this is an ancient question but I thought I'd comment for those who stumble across it. – Mike Stoddart Jun 26 '17 at 17:59