Is there a way to list Django signals? - django

Is there a way to see which signals have been set in Django?

It's not really exposed in docs but Signal is just a class that contains a list of receivers which are called on event. You can manually check this list:
from django.db.models.signals import *
for signal in [pre_save, pre_init, pre_delete, post_save, post_delete, post_init, post_syncdb]:
# print a List of connected listeners
print signal.receivers

There's a django app called
django-debug-toolbar which adds a little toolbar at the top of all django served pages providing info related to the backend of the page's rendering, such as how many queries were executed, how much time they each took, etc. It also prints out signals. I don't use signals in my app, so I have never used that feature, but it's there.

I wrote little command that shows all signal listeners: https://gist.github.com/1264102
You can modify it to show signals only.

If you want to list only the connected receivers for a specific signal on a specific model, you can look at _live_receivers. For instance, if you want to list the connected post_save hooks for a model named MyModel, you can do:
from django.db.models.signals import post_save
from models import MyModel
print(post_save._live_receivers(MyModel))
I found this approach in the Django source code by looking for how has_listeners works: https://github.com/django/django/blob/3eb679a86956d9eedf24492f0002de002f7180f5/django/dispatch/dispatcher.py#L153

Related

Why use signals in Django?

I have read lots of documentation and articles about using signals in Django, but I cannot understand the concept.
What is the purpose of using signals in Django?
How does it work?
Please explain the concept of signals and how to use it in Django code.
The Django Signals is a strategy to allow decoupled applications to get notified when certain events occur. Let’s say you want to invalidate a cached page everytime a given model instance is updated, but there are several places in your code base that this model can be updated. You can do that using signals, hooking some pieces of code to be executed everytime this specific model’s save method is trigged.
Another common use case is when you have extended the Custom Django User by using the Profile strategy through a one-to-one relationship. What we usually do is use a “signal dispatcher” to listen for the User’s post_save event to also update the Profile instance as well.

How can I trigger a function when a user registers in django?

I took over a django web app and am still relatively new to django. I want to trigger a function whenever a new user registers on the website. But there is no code in the project to process the user registration. It all seems to happen under the hood. So I don't know where could put such a function call. The web app uses django.contrib.auth.
Additionally: How can I trigger a function when an account is activated?
You can use the signals to trigger an event when you save anything in your db, include the User from auth. You can see the django doc about this.
In your case, I think that the best way is like:
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.contrib.auth.models import user
#receiver(post_save, sender=User)
def user_saved(sender, instance, **kwargs):
...
In the kwargs you can see, for example, if object is created or modified. The sender is the Class and the instance is the object.

I want to use a signal which emitt just after log out in django allauth, just like user_logged_in

I want to use a django all auth signal which emit just after log out, just like user_logged_in, but I didn't find any signal for log out.
Couldn't you just use the core Django signal from django.contrib.auth, user_logged_out?
https://docs.djangoproject.com/en/1.8/ref/contrib/auth/#django.contrib.auth.signals.user_logged_out
Good luck!

Django TastyPie, how to trigger action after POST with ManyToMany fields?

I have a REST API built using Django and TastyPie. My goal is to add a task to my job queue when new data is POSTed to a particular model.
I was going to hook into post_save and trigger then but the model contains ManyToMany relationships and so the post_save is triggered before the m2m relationships update and hooking into the m2m_changed signal seems messy. I get multiple signal events and my code will need to check the instance after each one and try and determine if it's ready to trigger the event. Some of the ManyToMany fields can be Null so when I get an m2m_changed signal I don't really know for sure if it's done saving.
Is there a correct way to do this? Does TastyPie allow me to hook into the POST event and do something at the end? All the things I have found point me at post_save events to do this.
Does Django have a way to signal me when all m2m updates for a given model instance are completed?
If you are using POST, then obj_update() does not appear to work for me. What did work was using obj_create() as follows:
class Resource(ModelResource):
def obj_create(self,bundle,**kwargs):
bundle = super(Resource,self).obj_create(bundle,**kwargs)
# Add code here
return bundle
One thing to note is that request is not included. I tried that and it gave me an error.
You should be able to override the obj_update method
class Resource(ModelResource):
def obj_update(self, bundle, request, **kwargs):
bundle = super(Resource, self).obj_update(bundle, **kwargs)
# queue your task here
return bundle

post_save in the admin

I have a application that i exclusively use with the admin.
I would like to send an email every time that a new object is created/modified, from my search, it seems that using the post_save would be the best way.
Unfortunately the doc is not really clear on that...
Can someone explain me > maybe with an example ?
Thanks
There are two ways. Either override the save function or use signals.
See the following excellent posts:
Django Signals
Django Signals vs Save (linked to archive.org original removed)
For a simple similar example using save have a look at my previous answer:
Send an e-mail notification when a Django CharField is modified via the admin site