Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Pre_delete Signal in django

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:)

like image 865
The Recruit Avatar asked Dec 13 '12 09:12

The Recruit


People also ask

What is pre save signal in Django?

Pre-save SignalThe function can live within models.py . In the above code block, you have defined your business logic in the validate_order() function and using the pre_save function, and you have connected the receiver function to the sender, which is the Order model.

What is the use of the Post_delete signal in Django?

Django Signals - post_delete()To notify another part of the application after the delete event of an object happens, you can use the post_delete signal.

How do you call a signal in Django?

There are two ways to send signals in Django. To send a signal, call either Signal. send() (all built-in signals use this) or Signal. send_robust() .

What kind of signals are there in Django?

There are 3 types of signal. pre_save/post_save: This signal works before/after the method save(). pre_delete/post_delete: This signal works before after delete a model's instance (method delete()) this signal is thrown.


1 Answers

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.

like image 82
Josh Smeaton Avatar answered Sep 29 '22 12:09

Josh Smeaton