Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to selectively suppress a post_save (or other) signal in Django?

I'm wondering whether it's possible to selectively suppress a Django signal (such as post_save or post_init) on object creation, or, alternatively, send it certain parameters.

What I have is a User object, which can be created in many different ways and places in my code. So to automatically assign a custom Profile object to each User, I use the post_save signal. However, in one specific case, there is extra information that I want to bind to the created Profile object. Passing it as arguments to the post_save signal would be great, but it doesn't look possible.

The other option is to manually create the Profile object, but then I need to that after the User is saved, otherwise the Profile cannot be bound to a User instance. Saving the User instance, however, results in another Profile being created via the function called by the signal.

And I can't just get the just-created Profile object, since that results in a 'Profile' object is unsubscriptable error. Any advice?

Update:

Here is an example of a possible situation:

def createUserProfile(sender, instance, created, **kwargs):
if created:  
    profile, created = Profile.objects.get_or_create(user=instance)
    if extra_param:
        profile.extra_param = extra_param
    profile.save()

post_save.connect(createUserProfile, sender=User)

def signup(request):
   ...
   extra_param = 'param'
   user.save()

How do I get the variable extra_param in the signup method to the createUserProfile method, where it is to be stored as part of the Profile object?

like image 859
Herman Schaaf Avatar asked Jan 27 '11 14:01

Herman Schaaf


People also ask

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.

Are Django signals asynchronous?

To answer directly: No. It's sync.

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.


1 Answers

Why this doesn't work for you?

user = User(...)
user.save()
# profile has been created transparently by post_save event
profile = user.profile
profile.extra_stuff = '...'
profile.save()

If you are obsessed with parameters passing to event, possible but evil:

user = User()
user._evil_extra_args = { ... }
user.save()

In event:
extra_args = getattr(user, '_evil_extra_args', False)

It is evil because people who will read your code will have no idea what the heck those _evil_extra_args is for and how does it work.

like image 76
Ski Avatar answered Oct 01 '22 04:10

Ski