Search code examples
pythondjangosignalsdjango-signals

django post_migrate signal issue


I am getting below error since I have below import line at my myproject/apps.py file. When I delete this import file I get error like Permission or Group can not be found

from django.contrib.auth.models import Group, Permission

error message;

C:\django\myproject>python manage.py migrate myproject
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line
353, in execute_from_command_line
    utility.execute()
  File "C:\Python27\lib\site-packages\django\core\management\__init__.py", line
327, in execute
    django.setup()
  File "C:\Python27\lib\site-packages\django\__init__.py", line 18, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "C:\Python27\lib\site-packages\django\apps\registry.py", line 85, in popu
late
    app_config = AppConfig.create(entry)
  File "C:\Python27\lib\site-packages\django\apps\config.py", line 90, in create

    module = import_module(entry)
  File "C:\Python27\lib\importlib\__init__.py", line 37, in import_module
    __import__(name)
  File "C:\django\myproject\myproject\apps.py", line 3, in <module>
    from django.contrib.auth.models import Group, Permission
  File "C:\Python27\lib\site-packages\django\contrib\auth\models.py", line 4, in
 <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "C:\Python27\lib\site-packages\django\contrib\auth\base_user.py", line 49
, in <module>
    class AbstractBaseUser(models.Model):
  File "C:\Python27\lib\site-packages\django\db\models\base.py", line 94, in __n
ew__
    app_config = apps.get_containing_app_config(module)
  File "C:\Python27\lib\site-packages\django\apps\registry.py", line 239, in get
_containing_app_config
    self.check_apps_ready()
  File "C:\Python27\lib\site-packages\django\apps\registry.py", line 124, in che
ck_apps_ready
    raise AppRegistryNotReady("Apps aren't loaded yet.")
django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

myproject/apps.py

from django.db.models.signals import post_migrate
from django.apps import AppConfig
from django.contrib.auth.models import Group, Permission


def create_group(name, permissions):
    group = Group.objects.create(name=name)
    [group.permissions.add(permission) for permission in permissions]


def define_company_groups(sender, **kwargs):
    permissions = [
        Permission.objects.get(codename='add_group1_profile'),
        Permission.objects.get(codename='change_group1_profile'),
    ]
    create_group('group1', permissions)


class MyAppConfig(AppConfig):
    name = 'myproject'


    def ready(self):
        post_migrate.connect(define_company_groups, sender=self)

I have also something in models.py to be sure that post_migrate is fired models.py;

from django.db import models

class testmodel(models.Model):

    field1 = models.CharField( max_length=10)
    field2 = models.CharField( max_length=10)
    field3 = models.CharField( max_length=10)

I have tried to add below line to init.py but it didnt help init.py;

default_app_config = 'myproject.apps.MyAppConfig'

setting.py

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
from django.contrib.messages import constants as messages

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'fhhc#5%c1gn*fdgf4o#a0d*@k)d56^sl*l)aydl5!_sk9_7'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
TEMPLATE_DEBUG = DEBUG

ADMINS = (
    # ('Your Name', 'your_email@example.com'),
)

ALLOWED_HOSTS = []

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

# MANAGERS = ADMINS
INTERNAL_IPS = ('127.0.0.1',)

# AUTH_USER_MODEL = ''
# AUTHENTICATION_BACKENDS = ('',)
LOGIN_URL = '/login'

SESSION_EXPIRATION_SECONDS = 3600
SESSION_EXPIRE_AT_BROWSER_CLOSE = True

ALLOWED_HOSTS = []
TIME_ZONE = 'GMT'

LANGUAGE_CODE = 'en-us'

LANGUAGES = (
    ('tr', 'Turkish'),
    ('en', 'English'),
    ('de', 'German'),
)

SITE_ID = 1
USE_I18N = True
USE_L10N = True
USE_TZ = True

# Where to look for translations *first*
LOCALE_PATHS = (os.path.join(BASE_DIR, 'locale'),
)

# MEDIA_ROOT = '/var/lib/myproject/media/'
MEDIA_URL = '/media/'

# STATIC_ROOT = '/usr/lib/myproject/static/'
# STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
STATIC_URL = '/static/'
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))

# Additional locations of static files
STATICFILES_DIRS = (
    # Put strings here, like "/home/html/static" or "C:/www/django/static".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(BASE_DIR, 'static'),
)

# List of finder classes that know how to find static files in various
# locations.
STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    'django.template.loaders.app_directories.Loader',
)

# FILE_UPLOAD_HANDLERS = ('',)

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.security.SecurityMiddleware',
)

ROOT_URLCONF = 'myproject.urls'

WSGI_APPLICATION = 'myproject.wsgi.application'

TEMPLATE_DIRS = (
    # Put strings here, like "/home/html/django_templates" or
    # "C:/www/django/templates".
    # Always use forward slashes, even on Windows.
    # Don't forget to use absolute paths, not relative paths.
    os.path.join(BASE_DIR, 'myproject/templates'),
    os.path.join(BASE_DIR, 'myapp1/templates'),
    os.path.join(BASE_DIR, 'myapp2/templates'),
    os.path.join(BASE_DIR, 'help/templates'),
)

# Application definition
INSTALLED_APPS = (
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django.contrib.admin',
    'registration',
    'myapp1',
    'myapp2',
    'help',
    'myproject.apps.MyAppConfig',
)

SESSION_SERIALIZER = 'django.contrib.sessions.serializers.JSONSerializer'

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'myproject_format': {
            'format':
                '%(asctime)s %(levelname)s [%(threadName)s]: %(message)s\n'
        },
    },
    'handlers': {
        'django_file': {
            'level': 'ERROR',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'django.log'),
            'formatter': 'myproject_format',
            'encoding': 'utf8',
        },
        'personal_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'myapp1.log'),
            'formatter': 'myproject_format',
            'encoding': 'utf8',
        },
        'commercial_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'myapp2.log'),
            'formatter': 'myproject_format',
            'encoding': 'utf8',
        },
        'help_file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': os.path.join(BASE_DIR, 'help.log'),
            'formatter': 'myproject_format',
            'encoding': 'utf8',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['django_file'],
            'propagate': True,
            'level': 'ERROR',
        },
        'personal': {
            'handlers': ['myapp1_file'],
            'propagate': True,
            'level': 'DEBUG',
        },
        'commercial': {
            'handlers': ['myapp2_file'],
            'propagate': True,
            'level': 'DEBUG',
        },
        'help': {
            'handlers': ['help_file'],
            'propagate': True,
            'level': 'DEBUG',
        },
    }
}


MESSAGE_TAGS = {
    messages.SUCCESS: 'fa fa-check',
    messages.INFO: 'fa fa-info',
    messages.ERROR: 'fa fa-times',
    messages.WARNING: 'fa fa-exclamation',
}

# **********************************************************************************************************************

if DEBUG:
    INTERNAL_IPS = ('127.0.0.1',)
    MIDDLEWARE_CLASSES += (
        'debug_toolbar.middleware.DebugToolbarMiddleware',
    )

    INSTALLED_APPS += (
        'debug_toolbar',
        'django_extensions',
    )

    DEBUG_TOOLBAR_PANELS = [
        'debug_toolbar.panels.versions.VersionsPanel',
        'debug_toolbar.panels.timer.TimerPanel',
        'debug_toolbar.panels.settings.SettingsPanel',
        'debug_toolbar.panels.headers.HeadersPanel',
        'debug_toolbar.panels.request.RequestPanel',
        'debug_toolbar.panels.sql.SQLPanel',
        'debug_toolbar.panels.staticfiles.StaticFilesPanel',
        'debug_toolbar.panels.templates.TemplatesPanel',
        'debug_toolbar.panels.cache.CachePanel',
        'debug_toolbar.panels.signals.SignalsPanel',
        'debug_toolbar.panels.logging.LoggingPanel',
        'debug_toolbar.panels.redirects.RedirectsPanel',
    ]

    DEBUG_TOOLBAR_CONFIG = {
        'INTERCEPT_REDIRECTS': False,
    }

Solution

  • The app.py is loaded before django models are initiated. Importing models there leads therefore to an error when code in django\db\models\base.py is executed.

    The solution is to move the import statements into the methods:

    def create_group(name, permissions):
        from django.contrib.auth.models import Group
    
        group = Group.objects.create(name=name)
        [group.permissions.add(permission) for permission in permissions]
    
    
    def define_company_groups(sender, **kwargs):
        from django.contrib.auth.models import Permission
        permissions = [
            Permission.objects.get(codename='add_group1_profile'),
            Permission.objects.get(codename='change_group1_profile'),
        ]
        create_group('group1', permissions)