You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django的apps.py中使用post_save信号触发AppRegistryNotReady错误咨询

解决Django中post_save信号触发AppRegistryNotReady错误的问题

问题描述

使用Django框架,自定义了User模型,信号逻辑放在独立的signals.py文件中。在apps.py的ready方法中引入信号后,post_migrate信号能正常工作,但连接post_save信号时触发了AppRegistryNotReady错误(提示Apps aren't loaded yet.)。

相关代码

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="meidanpk@gmail.com",
            password=password 
        )
        user.is_active= True
        User.objects.save_me(user)
        subject = 'Meidan Account'
        message = password
        from_email = settings.EMAIL_HOST_USER
        recipient_list = ['ahmedyasin1947@gmail.com']
        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)

报错信息

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.

问题原因及解决办法

核心问题

报错根源是在apps.py的模块级别提前调用了get_user_model()。Django启动时会先加载所有AppConfig类,此时应用还未完全初始化,提前获取User模型会触发AppRegistryNotReady错误。post_migrate信号能正常工作是因为它的sender是当前AppConfig(self),不需要提前获取User模型;而post_save信号需要传入User模型作为sender,模块顶部提前获取User的操作打乱了初始化顺序。

修复步骤

  1. 将get_user_model()移到ready方法内部:避免在模块加载阶段调用模型相关方法,确保应用初始化完成后再获取User模型。
  2. 修复signals.py中的缺陷:补充缺失的User和settings导入,重命名同名函数避免逻辑覆盖。

修正后的代码

修正后的apps.py

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

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

    def ready(self):
        from django.contrib.auth import get_user_model
        from accounts.signals import generate_banks, create_first_account_on_migrate, create_first_account_on_save
        
        User = get_user_model()
        post_migrate.connect(generate_banks, sender=self)
        post_migrate.connect(create_first_account_on_migrate, sender=self)
        post_save.connect(create_first_account_on_save, sender=User)

修正后的signals.py

import secrets
from django.conf import settings
from django.core.mail import send_mail
from django.contrib.auth import get_user_model

User = get_user_model()

def create_first_account_on_migrate(sender, **kwargs):
    if sender.name == 'accounts':
        try:
            user = User.objects.get_user_by_username("meidan")
            if user:
                return
        except User.DoesNotExist:
            password = secrets.token_hex(4)
            user = User.objects.create(
                username="meidan",
                email="meidanpk@gmail.com",
                password=password 
            )
            user.is_active = True
            User.objects.save_me(user)
            subject = 'Meidan Account'
            message = password
            from_email = settings.EMAIL_HOST_USER
            recipient_list = ['ahmedyasin1947@gmail.com']
            send_mail(subject, message, from_email, recipient_list, fail_silently=False)


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

额外说明

  • Django中所有需要获取模型的操作,都应放在ready方法内部或确保在应用完全加载后执行。
  • 信号函数中查询User时,建议用try...except User.DoesNotExist捕获异常,避免查询不到用户时抛出错误。
  • 禁止定义同名函数,否则会覆盖之前的函数定义,导致逻辑丢失。

内容的提问来源于stack exchange,提问作者Ahmed Yasin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 16:52:48