diff --git a/django/utils/module_loading.py b/django/utils/module_loading.py
index 9bcdd27..f251035 100644
--- a/django/utils/module_loading.py
+++ b/django/utils/module_loading.py
@@ -1,26 +1,60 @@
-import os
 import imp
+import os
+import sys
 
-def module_has_submodule(mod, submod_name):
-    # If the module was loaded from an egg, __loader__ will be set and
-    # its find_module must be used to search for submodules.
-    loader = getattr(mod, '__loader__', None)
-    if loader:
-        mod_path = "%s.%s" % (mod.__name__.rsplit('.',1)[-1], submod_name)
-        x = loader.find_module(mod_path)
-        if x is None:
-            # zipimport.zipimporter.find_module is documented to take
-            # dotted paths but in fact through Python 2.7 is observed
-            # to require os.sep in place of dots...so try using os.sep
-            # if the dotted path version failed to find the requested
-            # submodule.
-            x = loader.find_module(mod_path.replace('.', os.sep))
-        return x is not None
 
-    try:
-        imp.find_module(submod_name, mod.__path__)
+def module_has_submodule(package, module_name):
+    """See if 'module' is in 'package'."""
+    name = ".".join([package.__name__, module_name])
+    if name in sys.modules:
         return True
-    except ImportError:
+    for finder in sys.meta_path:
+        if finder.find_module(name):
+            return True
+    for entry in package.__path__:  # No __path__, then not a package.
+        try:
+            # Try the cached finder.
+            finder = sys.path_importer_cache[entry]
+            if finder is None:
+                # Implicit import machinery should be used.
+                try:
+                    file_, _, _ = imp.find_module(module_name, [entry])
+                    if file_:
+                        file_.close()
+                    return True
+                except ImportError:
+                    continue
+            # Else see if the finder knows of a loader.
+            elif finder.find_module(name):
+                return True
+            else:
+                continue
+        except KeyError:
+            # No cached finder, so try and make one.
+            for hook in sys.path_hooks:
+                try:
+                    finder = hook(entry)
+                    # XXX Could cache in sys.path_importer_cache
+                    if finder.find_module(name):
+                        return True
+                    else:
+                        # Once a finder is found, stop the search.
+                        break
+                except ImportError:
+                    # Continue the search for a finder.
+                    continue
+            else:
+                # No finder found.
+                # Try the implicit import machinery if searching a directory.
+                if os.path.isdir(entry):
+                    try:
+                        file_, _, _ = imp.find_module(module_name, [entry])
+                        if file_:
+                            file_.close()
+                        return True
+                    except ImportError:
+                        pass
+                # XXX Could insert None or NullImporter
+    else:
+        # Exhausted the search, so the module cannot be found.
         return False
-
-
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 5902e8d..2c8b151 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -1,19 +1,15 @@
 # -*- coding: utf-8 -*-
-from django.conf import settings
-
-if __name__ == '__main__':
-    # When running this file in isolation, we need to set up the configuration
-    # before importing 'template'.
-    settings.configure()
 
-from datetime import datetime, timedelta
-import time
 import os
 import sys
+import time
 import traceback
 import unittest
+from datetime import datetime, timedelta
+from zipimport import zipimporter
 
 from django import template
+from django.conf import settings
 from django.core import urlresolvers
 from django.template import loader
 from django.template.loaders import app_directories, filesystem, cached
@@ -1317,8 +1313,27 @@ class Templates(unittest.TestCase):
         }
 
 
-class TemplateTagLoading(unittest.TestCase):
+class TestFinder(object):
+    def __init__(self, *args, **kwargs):
+        self.importer = zipimporter(*args, **kwargs)
+    
+    def find_module(self, path):
+        importer = self.importer.find_module(path)
+        if importer is None:
+            return
+        return TestLoader(importer)
+
+class TestLoader(object):
+    def __init__(self, importer):
+        self.importer = importer
+    
+    def load_module(self, name):
+        mod = self.importer.load_module(name)
+        mod.__loader__ = self
+        return mod
 
+
+class TemplateTagLoading(unittest.TestCase):
     def setUp(self):
         self.old_path = sys.path
         self.old_apps = settings.INSTALLED_APPS
@@ -1351,6 +1366,14 @@ class TemplateTagLoading(unittest.TestCase):
         except template.TemplateSyntaxError, e:
             self.assertTrue('ImportError' in e.args[0])
             self.assertTrue('Xtemplate' in e.args[0])
+    
+    def test_custom_loader_error(self):
+        sys.path_hooks.insert(0, TestFinder)
+        sys.path_importer_cache.clear()
+        
+        self.test_load_error_egg()
+        
+        sys.path_hooks.pop(0)
 
     def test_load_working_egg(self):
         ttext = "{% load working_egg %}"
