Wiped get_commands() cache when INSTALLED_APPS changes.
Refs #21018, #21688.
This commit is contained in:
parent
8a2f304a79
commit
f17d00278e
|
@ -11,15 +11,12 @@ from django.conf import settings
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.core.management.base import BaseCommand, CommandError, handle_default_options
|
from django.core.management.base import BaseCommand, CommandError, handle_default_options
|
||||||
from django.core.management.color import color_style
|
from django.core.management.color import color_style
|
||||||
|
from django.utils import lru_cache
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
|
||||||
# For backwards compatibility: get_version() used to be in this module.
|
# For backwards compatibility: get_version() used to be in this module.
|
||||||
from django import get_version
|
from django import get_version
|
||||||
|
|
||||||
# A cache of loaded commands, so that call_command
|
|
||||||
# doesn't have to reload every time it's called.
|
|
||||||
_commands = None
|
|
||||||
|
|
||||||
|
|
||||||
def find_commands(management_dir):
|
def find_commands(management_dir):
|
||||||
"""
|
"""
|
||||||
|
@ -85,6 +82,7 @@ def load_command_class(app_name, name):
|
||||||
return module.Command()
|
return module.Command()
|
||||||
|
|
||||||
|
|
||||||
|
@lru_cache.lru_cache(maxsize=None)
|
||||||
def get_commands():
|
def get_commands():
|
||||||
"""
|
"""
|
||||||
Returns a dictionary mapping command names to their callback applications.
|
Returns a dictionary mapping command names to their callback applications.
|
||||||
|
@ -107,34 +105,32 @@ def get_commands():
|
||||||
The dictionary is cached on the first call and reused on subsequent
|
The dictionary is cached on the first call and reused on subsequent
|
||||||
calls.
|
calls.
|
||||||
"""
|
"""
|
||||||
global _commands
|
commands = {name: 'django.core' for name in find_commands(__path__[0])}
|
||||||
if _commands is None:
|
|
||||||
_commands = dict((name, 'django.core') for name in find_commands(__path__[0]))
|
|
||||||
|
|
||||||
# Find the installed apps
|
# Find the installed apps
|
||||||
|
try:
|
||||||
|
settings.INSTALLED_APPS
|
||||||
|
except ImproperlyConfigured:
|
||||||
|
# Still useful for commands that do not require functional
|
||||||
|
# settings, like startproject or help.
|
||||||
|
app_names = []
|
||||||
|
else:
|
||||||
|
# Setup Django outside of the try/except block to avoid catching
|
||||||
|
# ImproperlyConfigured errors that aren't caused by the absence of
|
||||||
|
# a settings module.
|
||||||
|
django.setup()
|
||||||
|
app_configs = apps.get_app_configs()
|
||||||
|
app_names = [app_config.name for app_config in app_configs]
|
||||||
|
|
||||||
|
# Find and load the management module for each installed app.
|
||||||
|
for app_name in app_names:
|
||||||
try:
|
try:
|
||||||
settings.INSTALLED_APPS
|
path = find_management_module(app_name)
|
||||||
except ImproperlyConfigured:
|
commands.update({name: app_name for name in find_commands(path)})
|
||||||
# Still useful for commands that do not require functional
|
except ImportError:
|
||||||
# settings, like startproject or help.
|
pass # No management module - ignore this app
|
||||||
app_names = []
|
|
||||||
else:
|
|
||||||
# Setup Django outside of the try/except block to avoid catching
|
|
||||||
# ImproperlyConfigured errors that aren't caused by the absence of
|
|
||||||
# a settings module.
|
|
||||||
django.setup()
|
|
||||||
app_configs = apps.get_app_configs()
|
|
||||||
app_names = [app_config.name for app_config in app_configs]
|
|
||||||
|
|
||||||
# Find and load the management module for each installed app.
|
return commands
|
||||||
for app_name in app_names:
|
|
||||||
try:
|
|
||||||
path = find_management_module(app_name)
|
|
||||||
_commands.update(dict((name, app_name) for name in find_commands(path)))
|
|
||||||
except ImportError:
|
|
||||||
pass # No management module - ignore this app
|
|
||||||
|
|
||||||
return _commands
|
|
||||||
|
|
||||||
|
|
||||||
def call_command(name, *args, **options):
|
def call_command(name, *args, **options):
|
||||||
|
|
|
@ -39,6 +39,9 @@ def update_installed_apps(**kwargs):
|
||||||
# Rebuild templatetags module cache.
|
# Rebuild templatetags module cache.
|
||||||
from django.template import base
|
from django.template import base
|
||||||
base.templatetags_modules[:] = []
|
base.templatetags_modules[:] = []
|
||||||
|
# Rebuild management commands cache
|
||||||
|
from django.core.management import get_commands
|
||||||
|
get_commands.cache_clear()
|
||||||
|
|
||||||
|
|
||||||
@receiver(setting_changed)
|
@receiver(setting_changed)
|
||||||
|
|
Loading…
Reference in New Issue