Opened 4 years ago
Closed 4 years ago
#32186 closed Bug (duplicate)
Application's `ready()` method doesn't called when app's author missed to define `default_app_config`
Reported by: | Anthony | Owned by: | nobody |
---|---|---|---|
Component: | Core (Other) | Version: | 3.1 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
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 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".
Later on, it is stated that
AppConfig.ready()
Subclasses can override this method to perform initialization tasks such as registering signals.
And finally, in Signals documentation page, it is suggested to import application's signals in .ready()
method.
It is fleetingly stated, though, in Configuring applications that:
If there is no
default_app_config
, Django uses the baseAppConfig
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 (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
Change History (2)
comment:1 by , 4 years ago
Type: | Uncategorized → Bug |
---|
comment:2 by , 4 years ago
Component: | Uncategorized → Core (Other) |
---|---|
Resolution: | → duplicate |
Status: | new → closed |
This is a duplicate of #31180, which will have default app configs automatically discovered from Django 3.2.