I have a function that is the receiver of signals from all models of the system. I want the signals to be interrupted when I am making an database dump population through a Django command, so it wouldn't be invoked when model instances are created by this mean.
This is my receiver function:
@receiver(post_save)
def trigger_payment(sender, instance=None, created=False, **kwargs):
from TreasuryManagementApp.models import PaymentApplicationTrigger
if instance.__class__.__name__ not in trigger_models:
return
strategies = EventStrategies()
application_triggers = PaymentApplicationTrigger.objects.filter(event_name__in=trigger_models[instance.__class__.__name__]['event_names'])
for application_trigger in application_triggers:
strategies.execute(application_trigger, instance)
And this is the code of my command where I attempt to disconnect the function from signals:
class Command(BaseCommand):
help = _("""Run this command to import partners and operators from plane files""")
def execute(self, *args, **kwargs):
from TreasuryManagementApp.controllers import trigger_payment
Signal.disconnect(trigger_payment)
self.import_partners()
self.import_operators()
self.import_dead_ones()
The problem is that this call to Signals.disconnect()
raises the following exception:
Traceback (most recent call last):
File "manage.py", line 15, in <module>
execute_from_command_line(sys.argv)
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/TaxistasVenv/lib/python3.7/site-packages/django/core/managemen
t/__init__.py", line 381, in execute_from_command_line
utility.execute()
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/TaxistasVenv/lib/python3.7/site-packages/django/core/managemen
t/__init__.py", line 375, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/TaxistasVenv/lib/python3.7/site-packages/django/core/managemen
t/base.py", line 316, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/taxistas/GeneralApp/management/commands/startdatabase.py", lin
e 21, in execute
call_command('import_people')
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/TaxistasVenv/lib/python3.7/site-packages/django/core/managemen
t/__init__.py", line 148, in call_command
return command.execute(*args, **defaults)
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/taxistas/GeneralApp/management/commands/import_people.py", lin
e 433, in execute
Signal.disconnect(trigger_payment)
File "/Users/hugovillalobos/Documents/Code/TaxistasProject/TaxistasVenv/lib/python3.7/site-packages/django/dispatch/dispa
tcher.py", line 138, in disconnect
with self.lock:
AttributeError: 'function' object has no attribute 'lock'
Use post_save
instead of Signal
. Documentation in here says: "All signals are django.dispatch.Signal instances", thus, you must disconnect or connect your instance, instead of the Signal
class.
from django.db.models.signals import post_save
class Command(BaseCommand):
help = _("""Run this command to import partners and operators from plane files""")
def execute(self, *args, **kwargs):
from TreasuryManagementApp.controllers import trigger_payment
post_save.disconnect(trigger_payment)
self.import_partners()
self.import_operators()
self.import_dead_ones()
post_save.connect(trigger_payment) # don't forget to reconnect