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 [email protected].
To post to this group, send email to [email protected].
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