Index: django/core/management/__init__.py
===================================================================
--- django/core/management/__init__.py	(revision 15908)
+++ django/core/management/__init__.py	(working copy)
@@ -14,50 +14,80 @@
 # doesn't have to reload every time it's called.
 _commands = None
 
-def find_commands(management_dir):
-    """
-    Given a path to a management directory, returns a list of all the command
-    names that are available.
+try:
+    from pkgutil import iter_modules
+except:
 
-    Returns an empty list if no commands are defined.
-    """
-    command_dir = os.path.join(management_dir, 'commands')
-    try:
-        return [f[:-3] for f in os.listdir(command_dir)
-                if not f.startswith('_') and f.endswith('.py')]
-    except OSError:
-        return []
+    # Python versions earlier than 2.5 don't have the iter_modules function
 
-def find_management_module(app_name):
-    """
-    Determines the path to the management module for the given app_name,
-    without actually importing the application or the management module.
+    def find_management_module(app_name):
+        """
+        Determines the path to the management module for the given app_name,
+        without actually importing the application or the management module.
 
-    Raises ImportError if the management module cannot be found for any reason.
-    """
-    parts = app_name.split('.')
-    parts.append('management')
-    parts.reverse()
-    part = parts.pop()
-    path = None
+        Raises ImportError if the management module cannot be found for any reason.
+        """
+        parts = app_name.split('.')
+        parts.append('management')
+        parts.reverse()
+        part = parts.pop()
+        path = None
 
-    # When using manage.py, the project module is added to the path,
-    # loaded, then removed from the path. This means that
-    # testproject.testapp.models can be loaded in future, even if
-    # testproject isn't in the path. When looking for the management
-    # module, we need look for the case where the project name is part
-    # of the app_name but the project directory itself isn't on the path.
-    try:
-        f, path, descr = imp.find_module(part,path)
-    except ImportError,e:
-        if os.path.basename(os.getcwd()) != part:
-            raise e
+        # When using manage.py, the project module is added to the path,
+        # loaded, then removed from the path. This means that
+        # testproject.testapp.models can be loaded in future, even if
+        # testproject isn't in the path. When looking for the management
+        # module, we need look for the case where the project name is part
+        # of the app_name but the project directory itself isn't on the path.
+        try:
+            f, path, descr = imp.find_module(part,path)
+        except ImportError,e:
+            if os.path.basename(os.getcwd()) != part:
+                raise e
 
-    while parts:
-        part = parts.pop()
-        f, path, descr = imp.find_module(part, path and [path] or None)
-    return path
+        while parts:
+            part = parts.pop()
+            f, path, descr = imp.find_module(part, path and [path] or None)
+        return path
 
+    def find_commands(app_name):
+        """
+        Given a path to a management directory, returns a list of all the command
+        names that are available.
+
+        Returns an empty list if no commands are defined.
+        """
+        management_dir = find_management_module(app_name)
+        command_dir = os.path.join(management_dir, 'commands')
+        try:
+            return [f[:-3] for f in os.listdir(command_dir)
+                    if not f.startswith('_') and f.endswith('.py')]
+        except OSError:
+            return []
+
+
+
+else:
+
+    # Python 2.5
+    # The iter_modules function has the advantage to be more cleaner and more
+    # generic: also finds packages in zip files, recognizes other file
+    # extensions than .py
+
+    def find_commands(app_name):
+        """
+        Given an application name, returns a list of all the commands found.
+
+        Raises ImportError if no commands are defined.
+        """
+        packages = {}
+        mgmt_package = "%s.management.commands" % app_name
+        # The next line imports the *package*, not all modules in the package
+        __import__(mgmt_package)
+        path = getattr(sys.modules[mgmt_package], '__path__', None)
+        return [i[1] for i in iter_modules(path)]
+
+
 def load_command_class(app_name, name):
     """
     Given a command name and an application name, returns the Command
@@ -93,7 +123,7 @@
     """
     global _commands
     if _commands is None:
-        _commands = dict([(name, 'django.core') for name in find_commands(__path__[0])])
+        _commands = dict([(name, 'django.core') for name in find_commands('django.core')])
 
         # Find the installed apps
         try:
@@ -113,9 +143,8 @@
         # Find and load the management module for each installed app.
         for app_name in apps:
             try:
-                path = find_management_module(app_name)
                 _commands.update(dict([(name, app_name)
-                                       for name in find_commands(path)]))
+                                       for name in find_commands(app_name)]))
             except ImportError:
                 pass # No management module - ignore this app
 
