From 3a1099e33080e42e7f4f17e9c91b9576ff912627 Mon Sep 17 00:00:00 2001 From: Karl Hobley Date: Wed, 27 Aug 2014 10:54:58 +0100 Subject: [PATCH] Make hooks and image formats importing work with Django 1.7 AppConfigs This also fixes #398 --- wagtail/tests/settings.py | 10 ++++++++- wagtail/utils/apps.py | 35 ++++++++++++++++++++++++++++++++ wagtail/wagtailcore/hooks.py | 15 +++----------- wagtail/wagtailimages/formats.py | 14 ++----------- 4 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 wagtail/utils/apps.py diff --git a/wagtail/tests/settings.py b/wagtail/tests/settings.py index 32426dba64..da8863e668 100644 --- a/wagtail/tests/settings.py +++ b/wagtail/tests/settings.py @@ -68,7 +68,6 @@ INSTALLED_APPS = [ 'wagtail.wagtailimages', 'wagtail.wagtailembeds', 'wagtail.wagtailsearch', - 'wagtail.wagtailredirects', 'wagtail.wagtailforms', 'wagtail.contrib.wagtailstyleguide', 'wagtail.contrib.wagtailsitemaps', @@ -81,6 +80,15 @@ if django.VERSION[:2] == (1, 6): INSTALLED_APPS.append('south') +# If we are using Django 1.7 install wagtailredirects with its appconfig +# Theres nothing special about wagtailredirects, we just need to have one +# app which uses AppConfigs to test that hooks load properly + +if django.VERSION[:2] == (1, 6): + INSTALLED_APPS.append('wagtail.wagtailredirects') +else: + INSTALLED_APPS.append('wagtail.wagtailredirects.apps.WagtailRedirectsAppConfig') + # As we don't have south migrations for tests, South thinks # the Django 1.7 migrations are South migrations. SOUTH_MIGRATION_MODULES = { diff --git a/wagtail/utils/apps.py b/wagtail/utils/apps.py new file mode 100644 index 0000000000..05bf8aa756 --- /dev/null +++ b/wagtail/utils/apps.py @@ -0,0 +1,35 @@ +try: + from importlib import import_module +except ImportError: + # for Python 2.6, fall back on django.utils.importlib (deprecated as of Django 1.7) + from django.utils.importlib import import_module + +import django +from django.conf import settings +from django.utils.module_loading import module_has_submodule + + +def get_app_modules(): + """ + Generator function that yields a module object for each installed app + yields tuples of (app_name, module) + """ + if django.VERSION[:2] == (1, 6): + # Django 1.6 + for app in settings.INSTALLED_APPS: + yield app, import_module(app) + else: + # Django 1.7+ + from django.apps import apps + for app in apps.get_app_configs(): + yield app.name, app.module + + +def get_app_submodules(submodule_name): + """ + Searches each app module for the specified submodule + yields tuples of (app_name, module) + """ + for name, module in get_app_modules(): + if module_has_submodule(module, submodule_name): + yield name, import_module('%s.%s' % (name, submodule_name)) diff --git a/wagtail/wagtailcore/hooks.py b/wagtail/wagtailcore/hooks.py index 958675b973..41955b9d30 100644 --- a/wagtail/wagtailcore/hooks.py +++ b/wagtail/wagtailcore/hooks.py @@ -1,9 +1,5 @@ -from django.conf import settings -try: - from importlib import import_module -except ImportError: - # for Python 2.6, fall back on django.utils.importlib (deprecated as of Django 1.7) - from django.utils.importlib import import_module +from wagtail.utils.apps import get_app_submodules + _hooks = {} @@ -40,12 +36,7 @@ _searched_for_hooks = False def search_for_hooks(): global _searched_for_hooks if not _searched_for_hooks: - for app_module in settings.INSTALLED_APPS: - try: - import_module('%s.wagtail_hooks' % app_module) - except ImportError: - continue - + list(get_app_submodules('wagtail_hooks')) _searched_for_hooks = True diff --git a/wagtail/wagtailimages/formats.py b/wagtail/wagtailimages/formats.py index d00b65b44d..3c5644a078 100644 --- a/wagtail/wagtailimages/formats.py +++ b/wagtail/wagtailimages/formats.py @@ -1,11 +1,6 @@ -from django.conf import settings from django.utils.html import escape -try: - from importlib import import_module -except ImportError: - # for Python 2.6, fall back on django.utils.importlib (deprecated as of Django 1.7) - from django.utils.importlib import import_module +from wagtail.utils.apps import get_app_submodules class Format(object): @@ -85,12 +80,7 @@ _searched_for_image_formats = False def search_for_image_formats(): global _searched_for_image_formats if not _searched_for_image_formats: - for app_module in settings.INSTALLED_APPS: - try: - import_module('%s.image_formats' % app_module) - except ImportError: - continue - + list(get_app_submodules('image_formats')) _searched_for_image_formats = True