﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
32186	Application's `ready()` method doesn't called when app's author missed to define `default_app_config`	Anthony	nobody	"I think, the issue is applied to documentation specifically, but the code can do better too.

If application is referenced in `INSTALLED_APPS` by package path rather than `AppConfig`s sublcass path, ''and'' application's author missed to define `default_app_config`, then application's initialization will be skipped silently. It leads to hard-to-debug bugs, especially with things that already hard-to-debug such as scheduling asynchronous jobs with signals.

== Details

In [https://docs.djangoproject.com/en/2.2/ref/applications/#for-application-authors ""Applications""] documentation page, it is stated that application author need to provide subclass of `AppConfig`. Then, the user of application need to reference it in `INSTALLED_APPS` setting either by app's package path, or by `AppConfig` subclass.

It is also stated that app's author ''can'' make the loading of his `AppConfig` subclass by pointing `default_app_config` variable in `__init__.py` to `AppConfig` subclass full dotted path:

 You can make your application load this AppConfig subclass by default as follows:

 {{{
  # rock_n_roll/__init__.py

  default_app_config = 'rock_n_roll.apps.RockNRollConfig'
 }}}

Note that is not ""required"", nor ""should"" - you just ""can"". I treat it as ""you can, if you will"".

[https://docs.djangoproject.com/en/3.1/ref/applications/#django.apps.AppConfig.ready Later on], it is stated that

 `AppConfig.ready()`
 Subclasses can override this method to perform initialization tasks such as registering signals.

And finally, in [https://docs.djangoproject.com/en/3.1/topics/signals/#connecting-receiver-functions ""Signals""] documentation page, it is suggested to import application's signals in `.ready()` method.

It is fleetingly stated, though, in [https://docs.djangoproject.com/en/3.1/ref/applications/#configuring-applications ""Configuring applications""] that:

 If there is no `default_app_config`, Django uses the base `AppConfig` class

Which means that application author's `AppConfig` subclass ''will not even evaluated'' - so, nor `.ready()` is called, too.

The docs should explicitly **warn** (at least) an user that is is the case if app's author missed to define `default_app_config`, or user itself referenced application not by full `AppConfig` class.

== The code

It can do better, too.

There is clear condition that custom `AppConfig` subclass is skipped, here:


{{{
        else:
            try:
                # If this works, the app module specifies an app config class.
                entry = module.default_app_config
            except AttributeError:
                # Otherwise, it simply uses the default app config class.
                return cls(entry, module)
}}}

github https://github.com/django/django/blob/stable/3.1.x/django/apps/config.py#L110

An user, again, should be explicitly warned (at least) that it is the case, for example with log event of `WARNING` level.

Silently ignoring such a crucial nuance is worst possible way. Users can ([https://stackoverflow.com/search?q=django+signals+not+working and will, in my experience]) assume, for example, that subclassing `AppConfig` and overriding `.ready()` method is enough for registering their signals, which is far from truth. The solution could be to use full `AppConfig` paths, but seems like no one using it.

In our current project, there is about 30 installed apps (w/o our own), and none of them referenced by `AppConfig`s subclasses:


{{{
INSTALLED_APPS = [
    'polymorphic',
    'watchman',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'collectfast',
    'django.contrib.staticfiles',
    'dal',
    'dal_select2',
    'dal_queryset_sequence',
    'django_admin_env_notice',
    'django.contrib.admin',
    'django.contrib.admindocs',
    'adminsortable2',
    'ckeditor',
    'ckeditor_uploader',
    'easy_pdf',
    'rest_framework',
    'django_filters',
    'djoser',
    'social_django',
    'rest_social_auth',
    'axes',
    'corsheaders',
    'drf_yasg',
    'django_extensions',
    'django.contrib.postgres',
    'psqlextra',
    'versatileimagefield',
]
}}}

The most popular reusable apps also suggest usage of just package path in their docs:

https://www.django-rest-framework.org/#installation
https://django-allauth.readthedocs.io/en/latest/installation.html#django
https://github.com/django-extensions/django-extensions#installing-it
https://github.com/adamchainz/django-cors-headers#setup"	Bug	closed	Core (Other)	3.1	Normal	duplicate			Unreviewed	0	0	0	0	0	0
