django-fieldsignals signals must be connected after the app cache is ready
invious opened this issue · comments
I put this at the end of my models file:
def print_all_field_changes(sender, instance, changed_fields=None, **kwargs):
for field, (old, new) in changed_fields.items():
PollHistory.objects.update_or_create(
poll=instance, changes="%s changed from %s to %s" % (field.name, old, new))
from fieldsignals import pre_save_changed
pre_save_changed.connect(print_all_field_changes, sender=Poll)
and get the following error when I tried to makemigrations myapp
:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/Users/aymon/Envs/dchw/lib/python2.7/site-packages/django/core/management/__init__.py", line 363, in execute_from_command_line
utility.execute()
File "/Users/aymon/Envs/dchw/lib/python2.7/site-packages/django/core/management/__init__.py", line 337, in execute
django.setup()
File "/Users/aymon/Envs/dchw/lib/python2.7/site-packages/django/__init__.py", line 27, in setup
apps.populate(settings.INSTALLED_APPS)
File "/Users/aymon/Envs/dchw/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
app_config.import_models()
File "/Users/aymon/Envs/dchw/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
self.models_module = import_module(models_module_name)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/importlib/__init__.py", line 37, in import_module
__import__(name)
File "/Users/aymon/Documents/workspace/Work/dchw/ec2_change_mon/updates/models.py", line 34, in <module>
pre_save_changed.connect(print_all_field_changes, sender=Instance)
File "/Users/aymon/Envs/dchw/lib/python2.7/site-packages/fieldsignals/signals.py", line 28, in connect
"django-fieldsignals signals must be connected after the app cache is ready. "
django.core.exceptions.AppRegistryNotReady: django-fieldsignals signals must be connected after the app cache is ready. Connect the signal in your AppConfig.ready() handler.
That's correct. Django recommends this for all signal receivers:
https://docs.djangoproject.com/en/1.11/topics/signals/#connecting-receiver-functions
In practice, signal handlers are usually defined in a signals submodule of the application they relate to. Signal receivers are connected in the ready() method of your application configuration class. If you’re using the receiver() decorator, simply import the signals submodule inside ready().
django-fieldsignals requires this because it needs to inspect the models during signal registration, so that has to happen after the app cache is ready.
I'm confused as to how to get this to work. I put this in the apps.py:
def ready(self):
from updates.models import print_all_field_changes
from fieldsignals import pre_save_changed
from updates.models import Instance
pre_save_changed.connect(print_all_field_changes, sender=Instance)
and the print_all_field_changes
is in models.py
but i put a breakpoint on print_all_field_changes
and the code never seems to get called
looks correct to me. is the ready() method getting called?
no it doesn't seem so I put a breakpoint on pre_save_changed and it isn't hitting. Do I have to do something special in settings or something? here is my full apps.py
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig
class UpdatesConfig(AppConfig):
name = 'updates'
def ready(self):
from updates.models import print_all_field_changes
from fieldsignals import pre_save_changed
from updates.models import Instance
pre_save_changed.connect(print_all_field_changes, sender=Instance)
That's all fine. You also need to tell django where to find your application class via a default_app_config
thing in your __init__.py
.
https://docs.djangoproject.com/en/1.11/ref/applications/#for-application-authors