diff --git a/django/utils/importlib.py b/django/utils/importlib.py
index ef4d0e4..fe3f546 100644
--- a/django/utils/importlib.py
+++ b/django/utils/importlib.py
@@ -34,3 +34,63 @@ def import_module(name, package=None):
         name = _resolve_name(name[level:], package, level)
     __import__(name)
     return sys.modules[name]
+
+
+def import_attribute(name, exception_handler=None):
+    """
+    Loads an object from an 'name', like in MIDDLEWARE_CLASSES and the likes.
+
+    Import paths should be: "mypackage.mymodule.MyObject". It then imports the
+    module up until the last dot and tries to get the attribute after that dot
+    from the imported module.
+
+    If the import path does not contain any dots, a TypeError is raised.
+
+    If the module cannot be imported, an ImportError is raised.
+
+    If the attribute does not exist in the module, a AttributeError is raised.
+
+    You can provide custom error handling using the optional exception_handler
+    argument which gets called with the exception type, the exception value and
+    the traceback object if there is an error during loading.
+
+    The exception_handler is not called if an invalid import path (one without
+    a dot in it) is provided.
+    """
+    if '.' not in name:
+        raise TypeError("'name' argument to "
+                        "'django.utils.importlib.import_attribute' must "
+                        "contain at least one dot.")
+    module_name, object_name = name.rsplit('.', 1)
+    try:
+        module = import_module(module_name)
+    except:
+        if callable(exception_handler):
+            exctype, excvalue, tb = sys.exc_info()
+            return exception_handler(name, exctype, excvalue, tb)
+        else:
+            raise
+    try: 
+        return getattr(module, object_name)
+    except:
+        if callable(exception_handler):
+            exctype, excvalue, tb = sys.exc_info()
+            return exception_handler(name, exctype, excvalue, tb)
+        else:
+            raise
+
+
+def iter_import_attributes(names, exception_handler=None):
+    """
+    Calls django.contrib.load.import_attribute on all items in the iterable
+    names and returns a generator that yields the objects to be loaded.
+
+    The exception_handler is propagated to import_attribute.
+
+    If the exception_handler does not return anything or returns None, the
+    value is ignored.
+    """
+    for name in names:
+        next = import_attribute(name, exception_handler)
+        if next:
+            yield next
diff --git a/tests/regressiontests/utils/importlib.py b/tests/regressiontests/utils/importlib.py
new file mode 100644
index 0000000..bccd0ce
--- /dev/null
+++ b/tests/regressiontests/utils/importlib.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+from __future__ import with_statement
+from django.contrib.auth.models import User, AnonymousUser
+from django.test.testcases import TestCase
+from django.utils.importlib import import_attribute, iter_import_attributes
+    
+
+class LoadTests(TestCase):
+        
+    def test_import_attribute(self):
+        obj = import_attribute('django.contrib.auth.models.User')
+        self.assertEqual(obj, User)
+        
+    def test_import_attribute_fail_type(self):
+        self.assertRaises(TypeError, import_attribute, 'notanimportpath')
+        
+    def test_import_attribute_fail_import(self):
+        self.assertRaises(ImportError, import_attribute,
+                          'django.contrib.auth.not_models.User')
+        
+    def test_import_attribute_fail_attribute(self):
+        self.assertRaises(AttributeError, import_attribute,
+                          'django.contrib.auth.models.NotAUser')
+        
+    def test_import_attribute_exception_handler(self):
+        class MyException(Exception): pass
+        def exc_handler(*args, **kwargs):
+            raise MyException
+        self.assertRaises(MyException, import_attribute,
+                          'django.contrib.auth.models.NotAUser', exc_handler)
+        self.assertRaises(MyException, import_attribute,
+                          'django.contrib.auth.not_models.User', exc_handler)
+        self.assertRaises(TypeError, import_attribute, 'notanimportpath')
+
+    def test_iter_import_attributes(self):
+        import_paths = ['django.contrib.auth.models.User',
+                        'django.contrib.auth.models.AnonymousUser']
+        objs = list(iter_import_attributes(import_paths))
+        self.assertEqual(len(objs), 2)
+        self.assertEqual(objs[0], User)
+        self.assertEqual(objs[1], AnonymousUser)
+        
+    def test_iter_import_attributes_propagates_exception_handler(self):
+        class MyException(Exception): pass
+        def exc_handler(*args, **kwargs):
+            raise MyException
+        gen = iter_import_attributes(['django.contrib.auth.models.User',
+                                      'django.contrib.auth.models.NotAUser'],
+                                      exc_handler)
+        user = gen.next()
+        self.assertEqual(user, User)
+        self.assertRaises(MyException, gen.next)
+    
+    def test_iter_import_attributes_ignore_exceptions(self):
+        def exc_handler(*args, **kwargs):
+            pass
+
+        import_paths = ['django.contrib.auth.models.User',
+                        'django.contrib.auth.models.NotAUser',
+                        'django.contrib.auth.models.AnonymousUser']
+        objs = list(iter_import_attributes(import_paths, exc_handler))
+        self.assertEqual(len(objs), 2)
+        self.assertEqual(objs[0], User)
+        self.assertEqual(objs[1], AnonymousUser)
diff --git a/tests/regressiontests/utils/tests.py b/tests/regressiontests/utils/tests.py
index e91adc9..242b7e2 100644
--- a/tests/regressiontests/utils/tests.py
+++ b/tests/regressiontests/utils/tests.py
@@ -20,3 +20,4 @@ from datetime_safe import *
 from baseconv import *
 from jslex import *
 from ipv6 import *
+from importlib import *
