Index: django/test/client.py
===================================================================
--- django/test/client.py	(revision 9975)
+++ django/test/client.py	(working copy)
@@ -19,6 +19,7 @@
 from django.utils.encoding import smart_str
 from django.utils.http import urlencode
 from django.utils.itercompat import is_iterable
+from django.utils.importlib import import_module
 from django.db import transaction, close_connection
 
 BOUNDARY = 'BoUnDaRyStRiNg'
@@ -175,7 +176,7 @@
         Obtains the current session variables.
         """
         if 'django.contrib.sessions' in settings.INSTALLED_APPS:
-            engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
+            engine = import_module(settings.SESSION_ENGINE)
             cookie = self.cookies.get(settings.SESSION_COOKIE_NAME, None)
             if cookie:
                 return engine.SessionStore(cookie.value)
@@ -398,7 +399,7 @@
         user = authenticate(**credentials)
         if user and user.is_active \
                 and 'django.contrib.sessions' in settings.INSTALLED_APPS:
-            engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
+            engine = import_module(settings.SESSION_ENGINE)
 
             # Create a fake request to store login details.
             request = HttpRequest()
@@ -433,7 +434,7 @@
 
         Causes the authenticated user to be logged out.
         """
-        session = __import__(settings.SESSION_ENGINE, {}, {}, ['']).SessionStore()
+        session = import_module(settings.SESSION_ENGINE).SessionStore()
         session.delete(session_key=self.cookies[settings.SESSION_COOKIE_NAME].value)
         self.cookies = SimpleCookie()
 
Index: django/db/models/loading.py
===================================================================
--- django/db/models/loading.py	(revision 9975)
+++ django/db/models/loading.py	(working copy)
@@ -3,6 +3,7 @@
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.datastructures import SortedDict
+from django.utils.importlib import import_module
 
 import sys
 import os
@@ -69,9 +70,10 @@
         """
         self.handled[app_name] = None
         self.nesting_level += 1
-        mod = __import__(app_name, {}, {}, ['models'])
-        self.nesting_level -= 1
-        if not hasattr(mod, 'models'):
+        try:
+            models = import_module('.models', app_name)
+        except ImportError:
+            self.nesting_level -= 1
             if can_postpone:
                 # Either the app has no models, or the package is still being
                 # imported by Python and the model module isn't available yet.
@@ -79,9 +81,10 @@
                 # populate).
                 self.postponed.append(app_name)
             return None
-        if mod.models not in self.app_store:
-            self.app_store[mod.models] = len(self.app_store)
-        return mod.models
+        self.nesting_level -= 1
+        if models not in self.app_store:
+            self.app_store[models] = len(self.app_store)
+        return models
 
     def app_cache_ready(self):
         """
Index: django/db/__init__.py
===================================================================
--- django/db/__init__.py	(revision 9975)
+++ django/db/__init__.py	(working copy)
@@ -3,6 +3,7 @@
 from django.core import signals
 from django.core.exceptions import ImproperlyConfigured
 from django.utils.functional import curry
+from django.utils.importlib import import_module
 
 __all__ = ('backend', 'connection', 'DatabaseError', 'IntegrityError')
 
@@ -13,13 +14,14 @@
     # Most of the time, the database backend will be one of the official
     # backends that ships with Django, so look there first.
     _import_path = 'django.db.backends.'
-    backend = __import__('%s%s.base' % (_import_path, settings.DATABASE_ENGINE), {}, {}, [''])
+    backend = import_module('.base',
+                            '%s%s' % (_import_path, settings.DATABASE_ENGINE))
 except ImportError, e:
     # If the import failed, we might be looking for a database backend
     # distributed external to Django. So we'll try that next.
     try:
         _import_path = ''
-        backend = __import__('%s.base' % settings.DATABASE_ENGINE, {}, {}, [''])
+        backend = import_module('.base', settings.DATABASE_ENGINE)
     except ImportError, e_user:
         # The database backend wasn't found. Display a helpful error message
         # listing all possible (built-in) database backends.
Index: django/conf/__init__.py
===================================================================
--- django/conf/__init__.py	(revision 9975)
+++ django/conf/__init__.py	(working copy)
@@ -11,6 +11,7 @@
 
 from django.conf import global_settings
 from django.utils.functional import LazyObject
+from django.utils import importlib
 
 ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
 
@@ -68,7 +69,7 @@
         self.SETTINGS_MODULE = settings_module
 
         try:
-            mod = __import__(self.SETTINGS_MODULE, {}, {}, [''])
+            mod = importlib.import_module(self.SETTINGS_MODULE)
         except ImportError, e:
             raise ImportError, "Could not import settings '%s' (Is it on sys.path? Does it have syntax errors?): %s" % (self.SETTINGS_MODULE, e)
 
@@ -88,7 +89,8 @@
         new_installed_apps = []
         for app in self.INSTALLED_APPS:
             if app.endswith('.*'):
-                appdir = os.path.dirname(__import__(app[:-2], {}, {}, ['']).__file__)
+                app_mod = importlib.import_module(app[:-2])
+                appdir = os.path.dirname(app_mod.__file__)
                 app_subdirs = os.listdir(appdir)
                 app_subdirs.sort()
                 for d in app_subdirs:
Index: django/core/servers/fastcgi.py
===================================================================
--- django/core/servers/fastcgi.py	(revision 9975)
+++ django/core/servers/fastcgi.py	(working copy)
@@ -12,6 +12,7 @@
 pass to this server.
 """
 
+from django.utils import importlib
 import sys, os
 
 __version__ = "0.1"
@@ -113,7 +114,7 @@
             'maxSpare': int(options["maxspare"]),
             'minSpare': int(options["minspare"]),
             'maxChildren': int(options["maxchildren"]),
-            'maxRequests': int(options["maxrequests"]), 
+            'maxRequests': int(options["maxrequests"]),
         }
         flup_module += '_fork'
     elif options['method'] in ('thread', 'threaded'):
@@ -128,7 +129,8 @@
     wsgi_opts['debug'] = False # Turn off flup tracebacks
 
     try:
-        WSGIServer = getattr(__import__('flup.' + flup_module, '', '', flup_module), 'WSGIServer')
+        module = importlib_import_module('.%s' % flup_module, 'flup')
+        WSGIServer = module.WSGIServer
     except:
         print "Can't import flup." + flup_module
         return False
Index: django/core/serializers/__init__.py
===================================================================
--- django/core/serializers/__init__.py	(revision 9975)
+++ django/core/serializers/__init__.py	(working copy)
@@ -17,6 +17,7 @@
 """
 
 from django.conf import settings
+from django.utils import importlib
 
 # Built-in serializers
 BUILTIN_SERIALIZERS = {
@@ -47,7 +48,7 @@
     directly into the global register of serializers. Adding serializers
     directly is not a thread-safe operation.
     """
-    module = __import__(serializer_module, {}, {}, [''])
+    module = importlib.import_module(serializer_module)
     if serializers is None:
         _serializers[format] = module
     else:
Index: django/core/urlresolvers.py
===================================================================
--- django/core/urlresolvers.py	(revision 9975)
+++ django/core/urlresolvers.py	(working copy)
@@ -14,6 +14,7 @@
 from django.utils.datastructures import MultiValueDict
 from django.utils.encoding import iri_to_uri, force_unicode, smart_str
 from django.utils.functional import memoize
+from django.utils.importlib import import_module
 from django.utils.regex_helper import normalize
 from django.utils.thread_support import currentThread
 
@@ -54,7 +55,7 @@
             lookup_view = lookup_view.encode('ascii')
             mod_name, func_name = get_mod_func(lookup_view)
             if func_name != '':
-                lookup_view = getattr(__import__(mod_name, {}, {}, ['']), func_name)
+                lookup_view = getattr(import_module(mod_name), func_name)
                 if not callable(lookup_view):
                     raise AttributeError("'%s.%s' is not a callable." % (mod_name, func_name))
         except (ImportError, AttributeError):
@@ -197,7 +198,7 @@
         try:
             return self._urlconf_module
         except AttributeError:
-            self._urlconf_module = __import__(self.urlconf_name, {}, {}, [''])
+            self._urlconf_module = import_module(self.urlconf_name)
             return self._urlconf_module
     urlconf_module = property(_get_urlconf_module)
 
@@ -215,7 +216,7 @@
         callback = getattr(self.urlconf_module, 'handler%s' % view_type)
         mod_name, func_name = get_mod_func(callback)
         try:
-            return getattr(__import__(mod_name, {}, {}, ['']), func_name), {}
+            return getattr(import_module(mod_name), func_name), {}
         except (ImportError, AttributeError), e:
             raise ViewDoesNotExist, "Tried %s. Error was: %s" % (callback, str(e))
 
Index: django/core/handlers/base.py
===================================================================
--- django/core/handlers/base.py	(revision 9975)
+++ django/core/handlers/base.py	(working copy)
@@ -3,6 +3,7 @@
 from django import http
 from django.core import signals
 from django.utils.encoding import force_unicode
+from django.utils.importlib import import_module
 
 class BaseHandler(object):
     # Changes that are always applied to a response (in this order).
@@ -35,7 +36,7 @@
                 raise exceptions.ImproperlyConfigured, '%s isn\'t a middleware module' % middleware_path
             mw_module, mw_classname = middleware_path[:dot], middleware_path[dot+1:]
             try:
-                mod = __import__(mw_module, {}, {}, [''])
+                mod = import_module(mw_module)
             except ImportError, e:
                 raise exceptions.ImproperlyConfigured, 'Error importing middleware %s: "%s"' % (mw_module, e)
             try:
Index: django/core/files/uploadhandler.py
===================================================================
--- django/core/files/uploadhandler.py	(revision 9975)
+++ django/core/files/uploadhandler.py	(working copy)
@@ -10,6 +10,7 @@
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
 from django.core.files.uploadedfile import TemporaryUploadedFile, InMemoryUploadedFile
+from django.utils import importlib
 
 __all__ = ['UploadFileException','StopUpload', 'SkipFile', 'FileUploadHandler',
            'TemporaryFileUploadHandler', 'MemoryFileUploadHandler',
@@ -201,7 +202,7 @@
     i = path.rfind('.')
     module, attr = path[:i], path[i+1:]
     try:
-        mod = __import__(module, {}, {}, [attr])
+        mod = importlib.import_module(module)
     except ImportError, e:
         raise ImproperlyConfigured('Error importing upload handler module %s: "%s"' % (module, e))
     except ValueError, e:
Index: django/core/files/storage.py
===================================================================
--- django/core/files/storage.py	(revision 9975)
+++ django/core/files/storage.py	(working copy)
@@ -8,6 +8,7 @@
 from django.core.files.move import file_move_safe
 from django.utils.encoding import force_unicode
 from django.utils.functional import LazyObject
+from django.utils.importlib import import_module
 from django.utils.text import get_valid_filename
 from django.utils._os import safe_join
 
@@ -230,7 +231,7 @@
         raise ImproperlyConfigured("%s isn't a storage module." % import_path)
     module, classname = import_path[:dot], import_path[dot+1:]
     try:
-        mod = __import__(module, {}, {}, [''])
+        mod = import_module(module)
     except ImportError, e:
         raise ImproperlyConfigured('Error importing storage module %s: "%s"' % (module, e))
     try:
Index: django/core/cache/__init__.py
===================================================================
--- django/core/cache/__init__.py	(revision 9975)
+++ django/core/cache/__init__.py	(working copy)
@@ -19,6 +19,7 @@
 from django.conf import settings
 from django.core import signals
 from django.core.cache.backends.base import InvalidCacheBackendError
+from django.utils import importlib
 
 # Name for use in settings file --> name of module in "backends" directory.
 # Any backend scheme that is not in this dictionary is treated as a Python
@@ -58,9 +59,10 @@
 def get_cache(backend_uri):
     scheme, host, params = parse_backend_uri(backend_uri)
     if scheme in BACKENDS:
-        module = __import__('django.core.cache.backends.%s' % BACKENDS[scheme], {}, {}, [''])
+        name = 'django.core.cache.backends.%s' % BACKENDS[scheme]
     else:
-        module = __import__(scheme, {}, {}, [''])
+        name = scheme
+    module = importlib.import_module(name)
     return getattr(module, 'CacheClass')(host, params)
 
 cache = get_cache(settings.CACHE_BACKEND)
Index: django/core/management/commands/startapp.py
===================================================================
--- django/core/management/commands/startapp.py	(revision 9975)
+++ django/core/management/commands/startapp.py	(working copy)
@@ -1,6 +1,7 @@
 import os
 
 from django.core.management.base import copy_helper, CommandError, LabelCommand
+from django.utils.importlib import import_module
 
 class Command(LabelCommand):
     help = "Creates a Django app directory structure for the given app name in the current directory."
@@ -26,7 +27,7 @@
 
         # Check that the app_name cannot be imported.
         try:
-            __import__(app_name)
+            import_module(app_name)
         except ImportError:
             pass
         else:
Index: django/core/management/commands/flush.py
===================================================================
--- django/core/management/commands/flush.py	(revision 9975)
+++ django/core/management/commands/flush.py	(working copy)
@@ -1,5 +1,6 @@
 from django.core.management.base import NoArgsCommand, CommandError
 from django.core.management.color import no_style
+from django.utils.importlib import import_module
 from optparse import make_option
 
 class Command(NoArgsCommand):
@@ -23,7 +24,7 @@
         # dispatcher events.
         for app_name in settings.INSTALLED_APPS:
             try:
-                __import__(app_name + '.management', {}, {}, [''])
+                import_module('.management', app_name)
             except ImportError:
                 pass
 
Index: django/core/management/commands/syncdb.py
===================================================================
--- django/core/management/commands/syncdb.py	(revision 9975)
+++ django/core/management/commands/syncdb.py	(working copy)
@@ -1,5 +1,6 @@
 from django.core.management.base import NoArgsCommand
 from django.core.management.color import no_style
+from django.utils.importlib import import_module
 from optparse import make_option
 import sys
 
@@ -30,7 +31,7 @@
         # dispatcher events.
         for app_name in settings.INSTALLED_APPS:
             try:
-                __import__(app_name + '.management', {}, {}, [''])
+                import_module('.management', app_name)
             except ImportError, exc:
                 # This is slightly hackish. We want to ignore ImportErrors
                 # if the "management" module itself is missing -- but we don't
Index: django/core/management/commands/startproject.py
===================================================================
--- django/core/management/commands/startproject.py	(revision 9975)
+++ django/core/management/commands/startproject.py	(working copy)
@@ -1,4 +1,5 @@
 from django.core.management.base import copy_helper, CommandError, LabelCommand
+from django.utils.importlib import import_module
 import os
 import re
 from random import choice
@@ -20,7 +21,7 @@
 
         # Check that the project_name cannot be imported.
         try:
-            __import__(project_name)
+            import_module(project_name)
         except ImportError:
             pass
         else:
Index: django/core/management/__init__.py
===================================================================
--- django/core/management/__init__.py	(revision 9975)
+++ django/core/management/__init__.py	(working copy)
@@ -5,6 +5,7 @@
 
 import django
 from django.core.management.base import BaseCommand, CommandError, handle_default_options
+from django.utils.importlib import import_module
 
 # For backwards compatibility: get_version() used to be in this module.
 get_version = django.get_version
@@ -63,8 +64,8 @@
     class instance. All errors raised by the import process
     (ImportError, AttributeError) are allowed to propagate.
     """
-    return getattr(__import__('%s.management.commands.%s' % (app_name, name),
-                   {}, {}, ['Command']), 'Command')()
+    module = import_module('%s.management.commands.%s' % (app_name, name))
+    return module.Command()
 
 def get_commands():
     """
@@ -104,12 +105,9 @@
         # Find the project directory
         try:
             from django.conf import settings
-            project_directory = setup_environ(
-                __import__(
-                    settings.SETTINGS_MODULE, {}, {},
-                    (settings.SETTINGS_MODULE.split(".")[-1],)
-                ), settings.SETTINGS_MODULE
-            )
+            module = import_module(settings.SETTINGS_MODULE.split('.', 1)[0])
+            project_directory = setup_environ(module,
+                                                settings.SETTINGS_MODULE)
         except (AttributeError, EnvironmentError, ImportError):
             project_directory = None
 
@@ -328,7 +326,7 @@
     # Import the project module. We add the parent directory to PYTHONPATH to 
     # avoid some of the path errors new users can have.
     sys.path.append(os.path.join(project_directory, os.pardir))
-    project_module = __import__(project_name, {}, {}, [''])
+    project_module = import_module(project_name)
     sys.path.pop()
 
     return project_directory
Index: django/templatetags/__init__.py
===================================================================
--- django/templatetags/__init__.py	(revision 9975)
+++ django/templatetags/__init__.py	(working copy)
@@ -1,7 +1,8 @@
 from django.conf import settings
+from django.utils import importlib
 
 for a in settings.INSTALLED_APPS:
     try:
-        __path__.extend(__import__(a + '.templatetags', {}, {}, ['']).__path__)
+        __path__.extend(importlib.import_module('.templatetags', a).__path__)
     except ImportError:
         pass
Index: django/views/i18n.py
===================================================================
--- django/views/i18n.py	(revision 9975)
+++ django/views/i18n.py	(working copy)
@@ -1,7 +1,8 @@
 from django import http
+from django.conf import settings
+from django.utils import importlib
 from django.utils.translation import check_for_language, activate, to_locale, get_language
 from django.utils.text import javascript_quote
-from django.conf import settings
 import os
 import gettext as gettext_module
 
@@ -128,7 +129,7 @@
     paths = []
     # first load all english languages files for defaults
     for package in packages:
-        p = __import__(package, {}, {}, [''])
+        p = importlib.import_module(package)
         path = os.path.join(os.path.dirname(p.__file__), 'locale')
         paths.append(path)
         try:
Index: django/views/debug.py
===================================================================
--- django/views/debug.py	(revision 9975)
+++ django/views/debug.py	(working copy)
@@ -6,6 +6,7 @@
 from django.conf import settings
 from django.template import Template, Context, TemplateDoesNotExist
 from django.utils.html import escape
+from django.utils.importlib import import_module
 from django.http import HttpResponse, HttpResponseServerError, HttpResponseNotFound
 from django.utils.encoding import smart_unicode, smart_str
 
@@ -67,7 +68,8 @@
             self.loader_debug_info = []
             for loader in template_source_loaders:
                 try:
-                    source_list_func = getattr(__import__(loader.__module__, {}, {}, ['get_template_sources']), 'get_template_sources')
+                    module = import_module(loader.__module__)
+                    source_list_func = module.get_template_sources
                     # NOTE: This assumes exc_value is the name of the template that
                     # the loader attempted to load.
                     template_list = [{'name': t, 'exists': os.path.exists(t)} \
Index: django/utils/importlib.py
===================================================================
--- django/utils/importlib.py	(revision 0)
+++ django/utils/importlib.py	(revision 0)
@@ -0,0 +1,36 @@
+# Taken from Python 2.7 with permission from/by the original author.
+import sys
+
+def _resolve_name(name, package, level):
+    """Return the absolute name of the module to be imported."""
+    if not hasattr(package, 'rindex'):
+        raise ValueError("'package' not set to a string")
+    dot = len(package)
+    for x in xrange(level, 1, -1):
+        try:
+            dot = package.rindex('.', 0, dot)
+        except ValueError:
+            raise ValueError("attempted relative import beyond top-level "
+                              "package")
+    return "%s.%s" % (package[:dot], name)
+
+
+def import_module(name, package=None):
+    """Import a module.
+
+    The 'package' argument is required when performing a relative import. It
+    specifies the package to use as the anchor point from which to resolve the
+    relative import to an absolute import.
+
+    """
+    if name.startswith('.'):
+        if not package:
+            raise TypeError("relative imports require the 'package' argument")
+        level = 0
+        for character in name:
+            if character != '.':
+                break
+            level += 1
+        name = _resolve_name(name[level:], package, level)
+    __import__(name)
+    return sys.modules[name]
Index: django/utils/translation/trans_real.py
===================================================================
--- django/utils/translation/trans_real.py	(revision 9975)
+++ django/utils/translation/trans_real.py	(working copy)
@@ -7,6 +7,7 @@
 import gettext as gettext_module
 from cStringIO import StringIO
 
+from django.utils.importlib import import_module
 from django.utils.safestring import mark_safe, SafeData
 from django.utils.thread_support import currentThread
 
@@ -125,7 +126,7 @@
 
     if settings.SETTINGS_MODULE is not None:
         parts = settings.SETTINGS_MODULE.split('.')
-        project = __import__(parts[0], {}, {}, [])
+        project = import_module(parts[0])
         projectpath = os.path.join(os.path.dirname(project.__file__), 'locale')
     else:
         projectpath = None
@@ -176,12 +177,7 @@
             res = _merge(projectpath)
 
         for appname in settings.INSTALLED_APPS:
-            p = appname.rfind('.')
-            if p >= 0:
-                app = getattr(__import__(appname[:p], {}, {}, [appname[p+1:]]), appname[p+1:])
-            else:
-                app = __import__(appname, {}, {}, [])
-
+            app = import_module(appname)
             apppath = os.path.join(os.path.dirname(app.__file__), 'locale')
 
             if os.path.isdir(apppath):
Index: django/contrib/comments/__init__.py
===================================================================
--- django/contrib/comments/__init__.py	(revision 9975)
+++ django/contrib/comments/__init__.py	(working copy)
@@ -3,6 +3,7 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.contrib.comments.models import Comment
 from django.contrib.comments.forms import CommentForm
+from django.utils.importlib import import_module
 
 DEFAULT_COMMENTS_APP = 'django.contrib.comments'
 
@@ -18,7 +19,7 @@
 
     # Try to import the package
     try:
-        package = __import__(comments_app, '', '', [''])
+        package = import_module(comments_app)
     except ImportError:
         raise ImproperlyConfigured("The COMMENTS_APP setting refers to "\
                                    "a non-existing package.")
Index: django/contrib/admin/__init__.py
===================================================================
--- django/contrib/admin/__init__.py	(revision 9975)
+++ django/contrib/admin/__init__.py	(working copy)
@@ -1,6 +1,7 @@
 from django.contrib.admin.options import ModelAdmin, HORIZONTAL, VERTICAL
 from django.contrib.admin.options import StackedInline, TabularInline
 from django.contrib.admin.sites import AdminSite, site
+from django.utils.importlib import import_module
 
 # A flag to tell us if autodiscover is running.  autodiscover will set this to
 # True while running, and False when it finishes.
@@ -36,7 +37,7 @@
         # fails silently -- apps that do weird things with __path__ might
         # need to roll their own admin registration.
         try:
-            app_path = __import__(app, {}, {}, [app.split('.')[-1]]).__path__
+            app_path = import_module(app).__path__
         except AttributeError:
             continue
 
@@ -51,6 +52,6 @@
 
         # Step 3: import the app's admin file. If this has errors we want them
         # to bubble up.
-        __import__("%s.admin" % app)
+        import_module("%s.admin" % app)
     # autodiscover was successful, reset loading flag.
     LOADING = False
Index: django/contrib/admin/views/template.py
===================================================================
--- django/contrib/admin/views/template.py	(revision 9975)
+++ django/contrib/admin/views/template.py	(working copy)
@@ -4,6 +4,7 @@
 from django.shortcuts import render_to_response
 from django.contrib.sites.models import Site
 from django.conf import settings
+from django.utils.importlib import import_module
 from django.utils.translation import ugettext_lazy as _
 
 
@@ -15,7 +16,7 @@
     # get a dict of {site_id : settings_module} for the validator
     settings_modules = {}
     for mod in settings.ADMIN_FOR:
-        settings_module = __import__(mod, {}, {}, [''])
+        settings_module = import_module(mod)
         settings_modules[settings_module.SITE_ID] = settings_module
     site_list = Site.objects.in_bulk(settings_modules.keys()).values()
     if request.POST:
Index: django/contrib/admindocs/views.py
===================================================================
--- django/contrib/admindocs/views.py	(revision 9975)
+++ django/contrib/admindocs/views.py	(working copy)
@@ -9,6 +9,7 @@
 from django.core import urlresolvers
 from django.contrib.admindocs import utils
 from django.contrib.sites.models import Site
+from django.utils.importlib import import_module
 from django.utils.translation import ugettext as _
 from django.utils.safestring import mark_safe
 import inspect, os, re
@@ -114,13 +115,13 @@
         return missing_docutils_page(request)
 
     if settings.ADMIN_FOR:
-        settings_modules = [__import__(m, {}, {}, ['']) for m in settings.ADMIN_FOR]
+        settings_modules = [import_module(m) for m in settings.ADMIN_FOR]
     else:
         settings_modules = [settings]
 
     views = []
     for settings_mod in settings_modules:
-        urlconf = __import__(settings_mod.ROOT_URLCONF, {}, {}, [''])
+        urlconf = import_module(settings_mod.ROOT_URLCONF)
         view_functions = extract_views_from_urlpatterns(urlconf.urlpatterns)
         if Site._meta.installed:
             site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
@@ -146,7 +147,7 @@
 
     mod, func = urlresolvers.get_mod_func(view)
     try:
-        view_func = getattr(__import__(mod, {}, {}, ['']), func)
+        view_func = getattr(import_module(mod), func)
     except (ImportError, AttributeError):
         raise Http404
     title, body, metadata = utils.parse_docstring(view_func.__doc__)
@@ -257,7 +258,7 @@
 def template_detail(request, template):
     templates = []
     for site_settings_module in settings.ADMIN_FOR:
-        settings_mod = __import__(site_settings_module, {}, {}, [''])
+        settings_mod = import_module(site_settings_module)
         if Site._meta.installed:
             site_obj = Site.objects.get(pk=settings_mod.SITE_ID)
         else:
Index: django/contrib/auth/__init__.py
===================================================================
--- django/contrib/auth/__init__.py	(revision 9975)
+++ django/contrib/auth/__init__.py	(working copy)
@@ -1,5 +1,6 @@
 import datetime
 from django.core.exceptions import ImproperlyConfigured
+from django.utils.importlib import import_module
 
 SESSION_KEY = '_auth_user_id'
 BACKEND_SESSION_KEY = '_auth_user_backend'
@@ -9,7 +10,7 @@
     i = path.rfind('.')
     module, attr = path[:i], path[i+1:]
     try:
-        mod = __import__(module, {}, {}, [attr])
+        mod = import_module(module)
     except ImportError, e:
         raise ImproperlyConfigured, 'Error importing authentication backend %s: "%s"' % (module, e)
     except ValueError, e:
Index: django/contrib/sessions/middleware.py
===================================================================
--- django/contrib/sessions/middleware.py	(revision 9975)
+++ django/contrib/sessions/middleware.py	(working copy)
@@ -3,10 +3,11 @@
 from django.conf import settings
 from django.utils.cache import patch_vary_headers
 from django.utils.http import cookie_date
+from django.utils.importlib import import_module
 
 class SessionMiddleware(object):
     def process_request(self, request):
-        engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
+        engine = import_module(settings.SESSION_ENGINE)
         session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
         request.session = engine.SessionStore(session_key)
 
Index: django/template/__init__.py
===================================================================
--- django/template/__init__.py	(revision 9975)
+++ django/template/__init__.py	(working copy)
@@ -52,6 +52,7 @@
 from inspect import getargspec
 from django.conf import settings
 from django.template.context import Context, RequestContext, ContextPopException
+from django.utils.importlib import import_module
 from django.utils.itercompat import is_iterable
 from django.utils.functional import curry, Promise
 from django.utils.text import smart_split
@@ -935,7 +936,7 @@
     lib = libraries.get(module_name, None)
     if not lib:
         try:
-            mod = __import__(module_name, {}, {}, [''])
+            mod = import_module(module_name)
         except ImportError, e:
             raise InvalidTemplateLibrary("Could not load template library from %s, %s" % (module_name, e))
         try:
Index: django/template/loaders/app_directories.py
===================================================================
--- django/template/loaders/app_directories.py	(revision 9975)
+++ django/template/loaders/app_directories.py	(working copy)
@@ -10,21 +10,14 @@
 from django.core.exceptions import ImproperlyConfigured
 from django.template import TemplateDoesNotExist
 from django.utils._os import safe_join
+from django.utils.importlib import import_module
 
 # At compile time, cache the directories to search.
 fs_encoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
 app_template_dirs = []
 for app in settings.INSTALLED_APPS:
-    i = app.rfind('.')
-    if i == -1:
-        m, a = app, None
-    else:
-        m, a = app[:i], app[i+1:]
     try:
-        if a is None:
-            mod = __import__(m, {}, {}, [])
-        else:
-            mod = getattr(__import__(m, {}, {}, [a]), a)
+        mod = import_module(app)
     except ImportError, e:
         raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0])
     template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
Index: django/template/context.py
===================================================================
--- django/template/context.py	(revision 9975)
+++ django/template/context.py	(working copy)
@@ -1,5 +1,6 @@
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
+from django.utils.importlib import import_module
 
 _standard_context_processors = None
 
@@ -62,7 +63,7 @@
 
     def update(self, other_dict):
         "Like dict.update(). Pushes an entire dictionary's keys and values onto the context."
-        if not hasattr(other_dict, '__getitem__'): 
+        if not hasattr(other_dict, '__getitem__'):
             raise TypeError('other_dict must be a mapping (dictionary-like) object.')
         self.dicts = [other_dict] + self.dicts
         return other_dict
@@ -77,7 +78,7 @@
             i = path.rfind('.')
             module, attr = path[:i], path[i+1:]
             try:
-                mod = __import__(module, {}, {}, [attr])
+                mod = import_module(module)
             except ImportError, e:
                 raise ImproperlyConfigured('Error importing request processor module %s: "%s"' % (module, e))
             try:
Index: django/template/loader.py
===================================================================
--- django/template/loader.py	(revision 9975)
+++ django/template/loader.py	(working copy)
@@ -22,6 +22,7 @@
 
 from django.core.exceptions import ImproperlyConfigured
 from django.template import Origin, Template, Context, TemplateDoesNotExist, add_to_builtins
+from django.utils.importlib import import_module
 from django.conf import settings
 
 template_source_loaders = None
@@ -51,7 +52,7 @@
             i = path.rfind('.')
             module, attr = path[:i], path[i+1:]
             try:
-                mod = __import__(module, globals(), locals(), [attr])
+                mod = import_module(module)
             except ImportError, e:
                 raise ImproperlyConfigured, 'Error importing template source loader %s: "%s"' % (module, e)
             try:
Index: AUTHORS
===================================================================
--- AUTHORS	(revision 9975)
+++ AUTHORS	(working copy)
@@ -75,6 +75,7 @@
     Chris Cahoon <chris.cahoon@gmail.com>
     Juan Manuel Caicedo <juan.manuel.caicedo@gmail.com>
     Trevor Caira <trevor@caira.com>
+    Brett Cannon <brett@python.org>
     Ricardo Javier Cárdenes Medina <ricardo.cardenes@gmail.com>
     Jeremy Carbaugh <jcarbaugh@gmail.com>
     carljm <carl@dirtcircle.com>
