Search code examples
pythonpython-3.xdjangodjango-modelsdjango-rest-framework

Can we use post_save signals in apps.py?


There. I'm using django python. I've custom user model. I've created a separate django signals file. there is my method. I'm importing them in my apps.py and wanting to use there. cause, post_migrate signals are working that way. but post_save is different cause that takes model. whereas postmigrate are working with app name. You better understand with following code.

signals.py

import secrets
from django.core.mail import send_mail
def create_first_account(sender, **kwargs):
    if sender.name == 'accounts':
        user = User.objects.get_user_by_username("meidan")
        if user:
            return None
        password = secrets.token_hex(4)
        user = User.objects.create(
            username="meidan",
            email="[email protected]",
            password=password 
        )
        user.is_active= True
        User.objects.save_me(user)
        subject = 'Meidan Account'
        message = password
        from_email = settings.EMAIL_HOST_USER
        recipient_list = ['[email protected]']
        send_mail(subject, message, from_email, recipient_list, fail_silently=False)



def create_first_account(sender,created, **kwargs):
    if sender.name == 'accounts':
        print(created)

apps.py

from django.apps import AppConfig
from django.db.models.signals import post_migrate,post_save
from django.contrib.auth import get_user_model

User = get_user_model()
class AccountsConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'accounts'

    def ready(self):
        from accounts.signals import generate_banks,create_first_account,create_first_account
        post_migrate.connect(generate_banks, sender=self)
        post_migrate.connect(create_first_account, sender=self)
        post_save.connect(create_first_account,sender=User)

right now getting error.

  File "/home/aa/playapp-backend/envMy/lib/python3.10/site-packages/django/apps/registry.py", line 201, in get_model
    self.check_apps_ready()
  File "/home/aa/playapp-backend/envMy/lib/python3.10/site-packages/django/apps/registry.py", line 136, in check_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

Solution

  • Access your models only when Apps are fully loaded:

    def ready(self):
        from django.contrib.auth import get_user_model
        User = get_user_model()
        #•••Rest of code•••

    get_user_model() will search for the currently active user model in your project hence it will search all Apps. Since all Apps aren’t ready yet like this one, you will get the error you see.