This is very old issue in Django: see ticket 
https://code.djangoproject.com/ticket/8280
I've attached the patch I'm already using for years to package my django 
application with py2exe.

I don't understand why the core team continues to use the current 
un-pythonic code to discover commands and fails to merge any of the fixes 
that have been proposed.

Johan


Op donderdag 10 april 2014 14:19:19 UTC+2 schreef Antonio Francisco Martín 
Romero:
>
> Hi everyone,
>
> I was using py2exe + Django 1.3 without problems. From Django 1.4 the way 
> to find the commands changed  and it tries to find .py files as you can see 
> in the find_commands() function in the file core/management/__init__.py . 
> When you compile Django using py2exe, your don't have .py files, just .pyc 
> and manage.exe won't have any command. I have tried to modify the 
> find_command() function but the result was negative. Also, I have tried to 
> run commands manually but the functions try to find .py files as well.
>
> Did anyone manage to do it?
>
> Cheers
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-users+unsubscr...@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/71e4944c-0b0c-4939-8514-10da0a4d667e%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
 django/core/management/__init__.py | 62 +++++++++-----------------------------
 1 file changed, 14 insertions(+), 48 deletions(-)

diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 5b0ad6c..62f0796 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -3,11 +3,14 @@ import os
 import sys
 from optparse import OptionParser, NO_DEFAULT
 import imp
+import warnings
+from pkgutil import iter_modules
 
 from django.core.exceptions import ImproperlyConfigured
 from django.core.management.base import BaseCommand, CommandError, handle_default_options
 from django.core.management.color import color_style
 from django.utils.importlib import import_module
+from django.utils._os import upath
 from django.utils import six
 
 # For backwards compatibility: get_version() used to be in this module.
@@ -17,54 +20,18 @@ from django import get_version
 # doesn't have to reload every time it's called.
 _commands = None
 
-def find_commands(management_dir):
+def find_commands(app_name):
     """
-    Given a path to a management directory, returns a list of all the command
-    names that are available.
+    Given an application name, returns a list of all the commands found.
 
-    Returns an empty list if no commands are defined.
+    Raises ImportError 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 []
-
-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
-
-    # 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 as e:
-        if os.path.basename(os.getcwd()) != part:
-            raise e
-    else:
-        if f:
-            f.close()
-
-    while parts:
-        part = parts.pop()
-        f, path, descr = imp.find_module(part, [path] if path else None)
-        if f:
-            f.close()
-    return path
+    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):
     """
@@ -99,7 +66,7 @@ def get_commands():
     """
     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
         from django.conf import settings
@@ -113,9 +80,8 @@ def get_commands():
         # 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
 

Reply via email to