159 lines
5.5 KiB
Python
159 lines
5.5 KiB
Python
import inspect
|
|
|
|
from django.apps import AppConfig
|
|
from django.conf import settings
|
|
from django.core.checks import Warning, register
|
|
from django.middleware.gzip import GZipMiddleware
|
|
from django.utils.module_loading import import_string
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
from debug_toolbar import settings as dt_settings
|
|
|
|
|
|
class DebugToolbarConfig(AppConfig):
|
|
name = "debug_toolbar"
|
|
verbose_name = _("Debug Toolbar")
|
|
|
|
def ready(self):
|
|
from debug_toolbar.toolbar import DebugToolbar
|
|
|
|
# Import the panels when the app is ready and call their ready() methods. This
|
|
# allows panels like CachePanel to enable their instrumentation immediately.
|
|
for cls in DebugToolbar.get_panel_classes():
|
|
cls.ready()
|
|
|
|
|
|
def check_template_config(config):
|
|
"""
|
|
Checks if a template configuration is valid.
|
|
|
|
The toolbar requires either the toolbars to be unspecified or
|
|
``django.template.loaders.app_directories.Loader`` to be
|
|
included in the loaders.
|
|
If custom loaders are specified, then APP_DIRS must be True.
|
|
"""
|
|
app_dirs = config.get("APP_DIRS", False)
|
|
loaders = config.get("OPTIONS", {}).get("loaders", None)
|
|
# By default the app loader is included.
|
|
has_app_loaders = (
|
|
loaders is None or "django.template.loaders.app_directories.Loader" in loaders
|
|
)
|
|
return has_app_loaders or app_dirs
|
|
|
|
|
|
@register
|
|
def check_middleware(app_configs, **kwargs):
|
|
from debug_toolbar.middleware import DebugToolbarMiddleware
|
|
|
|
errors = []
|
|
gzip_index = None
|
|
debug_toolbar_indexes = []
|
|
|
|
if all(not check_template_config(config) for config in settings.TEMPLATES):
|
|
errors.append(
|
|
Warning(
|
|
"At least one DjangoTemplates TEMPLATES configuration needs "
|
|
"to use django.template.loaders.app_directories.Loader or "
|
|
"have APP_DIRS set to True.",
|
|
hint=(
|
|
"Include django.template.loaders.app_directories.Loader "
|
|
'in ["OPTIONS"]["loaders"]. Alternatively use '
|
|
"APP_DIRS=True for at least one "
|
|
"django.template.backends.django.DjangoTemplates "
|
|
"backend configuration."
|
|
),
|
|
id="debug_toolbar.W006",
|
|
)
|
|
)
|
|
|
|
# If old style MIDDLEWARE_CLASSES is being used, report an error.
|
|
if settings.is_overridden("MIDDLEWARE_CLASSES"):
|
|
errors.append(
|
|
Warning(
|
|
"debug_toolbar is incompatible with MIDDLEWARE_CLASSES setting.",
|
|
hint="Use MIDDLEWARE instead of MIDDLEWARE_CLASSES",
|
|
id="debug_toolbar.W004",
|
|
)
|
|
)
|
|
return errors
|
|
|
|
# Determine the indexes which gzip and/or the toolbar are installed at
|
|
for i, middleware in enumerate(settings.MIDDLEWARE):
|
|
if is_middleware_class(GZipMiddleware, middleware):
|
|
gzip_index = i
|
|
elif is_middleware_class(DebugToolbarMiddleware, middleware):
|
|
debug_toolbar_indexes.append(i)
|
|
|
|
if not debug_toolbar_indexes:
|
|
# If the toolbar does not appear, report an error.
|
|
errors.append(
|
|
Warning(
|
|
"debug_toolbar.middleware.DebugToolbarMiddleware is missing "
|
|
"from MIDDLEWARE.",
|
|
hint="Add debug_toolbar.middleware.DebugToolbarMiddleware to "
|
|
"MIDDLEWARE.",
|
|
id="debug_toolbar.W001",
|
|
)
|
|
)
|
|
elif len(debug_toolbar_indexes) != 1:
|
|
# If the toolbar appears multiple times, report an error.
|
|
errors.append(
|
|
Warning(
|
|
"debug_toolbar.middleware.DebugToolbarMiddleware occurs "
|
|
"multiple times in MIDDLEWARE.",
|
|
hint="Load debug_toolbar.middleware.DebugToolbarMiddleware only "
|
|
"once in MIDDLEWARE.",
|
|
id="debug_toolbar.W002",
|
|
)
|
|
)
|
|
elif gzip_index is not None and debug_toolbar_indexes[0] < gzip_index:
|
|
# If the toolbar appears before the gzip index, report an error.
|
|
errors.append(
|
|
Warning(
|
|
"debug_toolbar.middleware.DebugToolbarMiddleware occurs before "
|
|
"django.middleware.gzip.GZipMiddleware in MIDDLEWARE.",
|
|
hint="Move debug_toolbar.middleware.DebugToolbarMiddleware to "
|
|
"after django.middleware.gzip.GZipMiddleware in MIDDLEWARE.",
|
|
id="debug_toolbar.W003",
|
|
)
|
|
)
|
|
return errors
|
|
|
|
|
|
@register
|
|
def check_panel_configs(app_configs, **kwargs):
|
|
"""Allow each panel to check the toolbar's integration for their its own purposes."""
|
|
from debug_toolbar.toolbar import DebugToolbar
|
|
|
|
errors = []
|
|
for panel_class in DebugToolbar.get_panel_classes():
|
|
for check_message in panel_class.run_checks():
|
|
errors.append(check_message)
|
|
return errors
|
|
|
|
|
|
def is_middleware_class(middleware_class, middleware_path):
|
|
try:
|
|
middleware_cls = import_string(middleware_path)
|
|
except ImportError:
|
|
return
|
|
return inspect.isclass(middleware_cls) and issubclass(
|
|
middleware_cls, middleware_class
|
|
)
|
|
|
|
|
|
@register
|
|
def check_panels(app_configs, **kwargs):
|
|
errors = []
|
|
panels = dt_settings.get_panels()
|
|
if not panels:
|
|
errors.append(
|
|
Warning(
|
|
"Setting DEBUG_TOOLBAR_PANELS is empty.",
|
|
hint="Set DEBUG_TOOLBAR_PANELS to a non-empty list in your "
|
|
"settings.py.",
|
|
id="debug_toolbar.W005",
|
|
)
|
|
)
|
|
return errors
|