3

I have a Django app that needs to receive the post_save signal when the user model is saved, without knowing about the main project directly. Here's the basic layout:

project/
    __init__.py
    settings.py
    models.py
app/
    __init__.py
    models.py
    signals.py

It must work with Django 1.6, so I can't use the ready() method. In app/__init__.py I have:

# app/__init__.py

import signals

And in app/signals.py:

# app/signals.py

from django.contrib.auth import get_user_model
from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=get_user_model())
def user_save_callback(sender, instance, **kwargs):
    ...

The installed apps in project/settings include:

# project/settings.py

INSTALLED_APPS = (
    ...
    'django.contrib.auth',
    'project',
    'app',
    ...

The custom user model is defined in project/models.py. The signals module is definitely being loaded with the correct user model (a quick print statement at the top of signals.py serves to demonstrate this).

However, my callback function never gets called when an instance of the user model is saved. The django-debug-toolbar helped me to verify that the receivers are not being registered. What gives? Any thoughts you might have are greatly appreciated ;)

----- EDIT -----

It ended up being a silly problem, so I'm not posting it as an Answer. It's a large project and there was another signal receiver somewhere else with the same name. The other one was getting defined after mine, which was overwriting it in the registry of receivers :P

I guess it's a lesson in naming conventions... If you're going to register a signal handler, name it something specific. Especially if there are multiple handlers for the same signal.

stett
  • 1,351
  • 1
  • 11
  • 24
  • Could you show the order of apps in `INSTALLED_APPS`? – alecxe Jun 27 '14 at 18:33
  • @alecxe - I assume you're wondering what order the apps were in. I updated the question to elucidate that point. – stett Jun 27 '14 at 18:53
  • Thanks, but where is `django.contrib.auth`? – alecxe Jun 27 '14 at 18:54
  • Good point - it's above the other apps. – stett Jun 27 '14 at 18:59
  • Looks like you are experiencing [this problem](http://stackoverflow.com/a/16541458/771848). – alecxe Jun 27 '14 at 19:11
  • But if I put `print(get_user_model())` at the top of `app/signals.py`, it correctly outputs ``, which seems to suggest that the apps are being installed in the correct order, and that it is able to correctly determine the user model. Maybe something changed since Django 1.5? – stett Jun 27 '14 at 19:35

1 Answers1

3

I just updated a project from 1.7 to 1.8 and ran into this issue.

I was replacing old 'auth.User'and django.contrib.auth.models.Userreferences and stumbled upon the following error:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.

Reading through the traceback I found out that I did the following in my models.py:

models.signals.post_save.connect(create_user_profile, sender=get_user_model())

This is the second time I got that issue, so the following might be a solution to others. Simply replace the get_user_modelfunction with a string or setting:

models.signals.post_save.connect(create_user_profile, sender=settings.AUTH_USER_MODEL)
Tobias Lorenz
  • 1,426
  • 11
  • 17
  • I'm new to django. This saved my day. Currently I'm using `sender='auth.User' `. One thing that I wanted to implement was have a dynamic user model that you cater for `email login` and `username login` based on api that is being queried. Not sure if that is even possible. Might have problem with setting the sender to string then. – pravin Feb 23 '18 at 11:38