M src/wiki/apps.py => src/wiki/apps.py +8 -0
@@ 1,7 1,15 @@
from django.apps import AppConfig
+from django.core.checks import register
from django.utils.translation import gettext_lazy as _
+from . import checks
+
class WikiConfig(AppConfig):
name = "wiki"
verbose_name = _("Wiki")
+
+ def ready(self):
+ register(checks.check_for_required_installed_apps, checks.Tags.required_installed_apps)
+ register(checks.check_for_obsolete_installed_apps, checks.Tags.obsolete_installed_apps)
+ register(checks.check_for_context_processors, checks.Tags.context_processors)
A src/wiki/checks.py => src/wiki/checks.py +71 -0
@@ 0,0 1,71 @@
+from django.apps import apps
+from django.core.checks import Error
+from wiki.compat import get_default_engine
+
+
+class Tags:
+ required_installed_apps = "required_installed_apps"
+ obsolete_installed_apps = "obsolete_installed_apps"
+ context_processors = "context_processors"
+
+
+REQUIRED_INSTALLED_APPS = (
+ # module name, package name, error code
+ ('mptt', 'django-mptt', 'E001'),
+ ('sekizai', 'django-sekizai', 'E002'),
+ ('django.contrib.humanize', 'django.contrib.humanize', 'E003'),
+ ('django.contrib.contenttypes', 'django.contrib.contenttypes', 'E004'),
+ ('django.contrib.sites', 'django.contrib.sites', 'E005'),
+)
+
+OBSOLETE_INSTALLED_APPS = (
+ # obsolete module name, new module name, error code
+ ('django_notify', 'django_nyt', 'E006'),
+)
+
+REQUIRED_CONTEXT_PROCESSORS = (
+ # context processor name, error code
+ ('django.contrib.auth.context_processors.auth', 'E007'),
+ ('django.template.context_processors.request', 'E008'),
+ ('sekizai.context_processors.sekizai', 'E009'),
+)
+
+
+def check_for_required_installed_apps(app_configs, **kwargs):
+ errors = []
+ for app in REQUIRED_INSTALLED_APPS:
+ if not apps.is_installed(app[0]):
+ errors.append(
+ Error(
+ 'needs %s in INSTALLED_APPS' % app[1],
+ id='wiki.%s' % app[2],
+ )
+ )
+ return errors
+
+
+def check_for_obsolete_installed_apps(app_configs, **kwargs):
+ errors = []
+ for app in OBSOLETE_INSTALLED_APPS:
+ if apps.is_installed(app[0]):
+ errors.append(
+ Error(
+ 'You need to change from %s to %s in INSTALLED_APPS and your urlconfig.' % (app[0], app[1]),
+ id='wiki.%s' % app[2],
+ )
+ )
+ return errors
+
+
+def check_for_context_processors(app_configs, **kwargs):
+ errors = []
+ context_processors = get_default_engine().context_processors
+ for context_processor in REQUIRED_CONTEXT_PROCESSORS:
+ if context_processor[0] not in context_processors:
+ errors.append(
+ Error(
+ "needs %s in TEMPLATE['OPTIONS']['context_processors']" % context_processor[0],
+ id='wiki.%s' % context_processor[1],
+ )
+ )
+ return errors
M src/wiki/compat.py => src/wiki/compat.py +14 -0
@@ 10,6 10,7 @@ except ImportError:
__all__ = [
'BuildAttrsCompat',
+ 'get_default_engine',
'include', 'url'
]
@@ 28,3 29,16 @@ class BuildAttrsCompat:
if kwargs is not None:
attrs.update(kwargs)
return attrs
+
+
+def get_default_engine():
+ """
+ Django >= 2.1 Engine.get_default() behaviour
+ """
+ from django.core.exceptions import ImproperlyConfigured
+ from django.template import engines
+ from django.template.backends.django import DjangoTemplates
+ for engine in engines.all():
+ if isinstance(engine, DjangoTemplates):
+ return engine.engine
+ raise ImproperlyConfigured('No DjangoTemplates backend is configured.')
M src/wiki/models/__init__.py => src/wiki/models/__init__.py +0 -54
@@ 1,6 1,3 @@
-from django.apps import apps
-from django.conf import settings as django_settings
-from django.core.exceptions import ImproperlyConfigured
from django.urls import base
from django import urls
from django import shortcuts
@@ 11,57 8,6 @@ from .pluginbase import * # noqa
from .urlpath import * # noqa
from django.utils.functional import lazy
-# TODO: Should the below stuff be executed a more logical place?
-# Follow Django's default_settings.py / settings.py pattern and put these
-# in d_s.py? That might be confusing, though.
-
-######################
-# Configuration stuff
-######################
-
-if not apps.is_installed('mptt'):
- raise ImproperlyConfigured('django-wiki: needs mptt in INSTALLED_APPS')
-
-if not apps.is_installed('sekizai'):
- raise ImproperlyConfigured('django-wiki: needs sekizai in INSTALLED_APPS')
-
-# if not apps.is_installed('django_nyt'):
-# raise ImproperlyConfigured('django-wiki: needs django_nyt in INSTALLED_APPS')
-
-if not apps.is_installed('django.contrib.humanize'):
- raise ImproperlyConfigured(
- 'django-wiki: needs django.contrib.humanize in INSTALLED_APPS')
-
-if not apps.is_installed('django.contrib.contenttypes'):
- raise ImproperlyConfigured(
- 'django-wiki: needs django.contrib.contenttypes in INSTALLED_APPS')
-
-if not apps.is_installed('django.contrib.sites'):
- raise ImproperlyConfigured(
- 'django-wiki: needs django.contrib.sites in INSTALLED_APPS')
-
-# Need to handle Django 1.8 'TEMPLATES', recognizing that users may still be
-# using 1.7 conventions/settings with 1.8.
-TEMPLATE_CONTEXT_PROCESSORS = getattr(django_settings, 'TEMPLATE_CONTEXT_PROCESSORS', [])
-if hasattr(django_settings, 'TEMPLATES'):
- # Django 1.8 compat
- backends = [b for b in django_settings.TEMPLATES if b.get('BACKEND', '') == 'django.template.backends.django.DjangoTemplates']
- if len(backends) == 1:
- TEMPLATE_CONTEXT_PROCESSORS = backends[0].get('OPTIONS', {}).get('context_processors', [])
-
-if 'django.contrib.auth.context_processors.auth' not in TEMPLATE_CONTEXT_PROCESSORS:
- raise ImproperlyConfigured(
- 'django-wiki: needs django.contrib.auth.context_processors.auth in TEMPLATE_CONTEXT_PROCESSORS')
-
-if not any(s in TEMPLATE_CONTEXT_PROCESSORS for s in ['django.core.context_processors.request',
- 'django.template.context_processors.request']):
- raise ImproperlyConfigured(
- 'django-wiki: needs django.core.context_processors.request or django.template.context_processors.request in TEMPLATE_CONTEXT_PROCESSORS')
-
-if apps.is_installed('django_notify'):
- raise ImproperlyConfigured(
- 'django-wiki: You need to change from django_notify to django_nyt in INSTALLED_APPS and your urlconfig.')
-
original_django_reverse = urls.reverse
A tests/core/test_checks.py => tests/core/test_checks.py +38 -0
@@ 0,0 1,38 @@
+import copy
+
+from django.conf import settings
+from django.test import TestCase
+from django.core.checks import Error, registry
+from wiki.checks import REQUIRED_CONTEXT_PROCESSORS, REQUIRED_INSTALLED_APPS, OBSOLETE_INSTALLED_APPS, Tags
+
+
+class CheckTests(TestCase):
+ def test_required_installed_apps(self):
+ for app in REQUIRED_INSTALLED_APPS:
+ with self.modify_settings(INSTALLED_APPS={'remove': [app[0]]}):
+ errors = registry.run_checks(tags=[Tags.required_installed_apps])
+ expected_errors = [
+ Error(
+ 'needs %s in INSTALLED_APPS' % app[1],
+ id='wiki.%s' % app[2],
+ )
+ ]
+ self.assertEqual(errors, expected_errors)
+
+ def test_required_context_processors(self):
+ for context_processor in REQUIRED_CONTEXT_PROCESSORS:
+ TEMPLATES = copy.deepcopy(settings.TEMPLATES)
+ TEMPLATES[0]['OPTIONS']['context_processors'] = [
+ cp
+ for cp in TEMPLATES[0]['OPTIONS']['context_processors']
+ if cp != context_processor[0]
+ ]
+ with self.settings(TEMPLATES=TEMPLATES):
+ errors = registry.run_checks(tags=[Tags.context_processors])
+ expected_errors = [
+ Error(
+ "needs %s in TEMPLATE['OPTIONS']['context_processors']" % context_processor[0],
+ id='wiki.%s' % context_processor[1],
+ )
+ ]
+ self.assertEqual(errors, expected_errors)