#5825 closed (fixed)
Customized actions for manage.py not working
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | Core (Management commands) | Version: | dev |
Severity: | Keywords: | custom actions manage.py | |
Cc: | eric@…, martin@…, micsco@…, elsdoerfer@…, ehs@… | Triage Stage: | Unreviewed |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Custom actions can be added, as described http://www.djangoproject.com/documentation/django-admin/#customized-actions
Following the instructions I am getting the error message: unknown command
To reproduce you can also copy the contents of the folder tests\modeltests\user_commands\management in an application subdirectory of your project.
The regression test for user_commands passes: it seems to use a different sys.path than when you run manage.py from the commandline...
Digging a bit deeper in the source file django\core\management\__init__.py
:
- The function imp.find_module in the method find_management_module is using sys.path to locate the management modules. The parent directory of your project is normally not on the path, so looking for an application package "project_name.app_name" doesn't find a module. Manage.py only has the project directory itself on the path.
- The find_commands method in the same source file is using a pretty hack-ish way to discover commands: it looks for files ending in .py. This misses compiled code with extensions as .pyo and .pyc and also doesn't work for source files packaged in a zip file (as produced by eg py2exe). The correct api is to use pkgutil.iter_modules (unfortunately only available in python 2.5)
(I'm willing to look at a patch for the issues, but need some guidance: For the first issue, I am a bit puzzled by the append and popping of the sys.path in the setup_environ method in the same file. For the second issue, it requires more changes and thinking to do it properly across different versions: is it worth the effort?)
Attachments (5)
Change History (30)
comment:1 by , 17 years ago
comment:3 by , 17 years ago
import os, sys sys.path.append(os.path.dirname(os.getcwd()))
how formatting works?
comment:4 by , 17 years ago
The correct directory is added to sys.path by the django.core.management.setup_environ() function. It is then, for some reason, removed again. Why is this function called, if not to setup the sys.path correctly?
Commenting out the line: 'sys.path.pop()' from this function will make customized actions work correctly.
comment:5 by , 17 years ago
Owner: | changed from | to
---|
comment:6 by , 17 years ago
Has patch: | set |
---|
by , 17 years ago
Attachment: | user_commands_path.patch added |
---|
Here is a very simple patch that will make sure that sys.path includes the project's containing directory while searching for the local app management modules.
comment:7 by , 17 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|
comment:9 by , 17 years ago
Needs tests: | set |
---|---|
Triage Stage: | Ready for checkin → Accepted |
comment:10 by , 17 years ago
Owner: | changed from | to
---|
I fully agree that the testing for manage.py and django-admin.py can be better. The current test suite elegantly bypasses them.
There is already a unit test for user commands, and I don't clearly see how I can improve on it: hence I'm removing myself as the owner of the issue. Maybe somebody else has some bright idea or view on this...
by , 16 years ago
Attachment: | user_command_with_test.patch added |
---|
comment:11 by , 16 years ago
I came across this bug as well over the weekend. Attached is a small patch (the current one here no longer applies) & a unit test for the fix.
comment:12 by , 16 years ago
Cc: | added |
---|
comment:13 by , 16 years ago
Cc: | added |
---|
comment:14 by , 16 years ago
Cc: | added |
---|
comment:15 by , 16 years ago
Needs tests: | unset |
---|---|
Triage Stage: | Accepted → Ready for checkin |
comment:17 by , 16 years ago
milestone: | → 1.0 |
---|
This is a sufficiently significant problem that it warrants attention before v1.0
comment:18 by , 16 years ago
Cc: | added |
---|
comment:20 by , 16 years ago
Cc: | added |
---|
comment:21 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
(In [8227]) Fixed #5825 -- Modified the custom command loader to allow for explicit specification of the project name, even if the project directory isn't in the python path. This brings custom command loading into alignment with application loading. Thanks to jdetaeye@… for the original report, and to abozanich for the patch.
comment:22 by , 16 years ago
A new ticket ##8280 was created to make sure the commands framework supports alternate ways of packaging.
The original patch on this ticket fixed that problem too.
comment:23 by , 16 years ago
Has patch: | unset |
---|---|
milestone: | 1.0 → 1.1 |
Resolution: | fixed |
Status: | closed → reopened |
Triage Stage: | Ready for checkin → Unreviewed |
The fix does not work, if say, we use a symbolic link from ~/bin to manage.py, or run manage.py from anywhere else, like running python myproject/manage.py
The current directory won't show up as the project name, so the custom commands aren't found.
Should I not be doing that?
comment:24 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
This bug was fixed, please file a new ticket or contact the mailing lists if you have a new bug/might have a bug.
by , 16 years ago
Attachment: | managepath.diff added |
---|
In django.core.management.init.py in find_management_module function to define path to management module of each application (user app as well as django core) used function find_module from standard imp. Function find_module is called iterately on each part of application name with project name.
If application is called "common", and project is called "holdem" then find_module first tries to import "holdem", then using it's path tries to import "common", then using it's path tries to import "management".
Before first call of find_module path is set to None. This makes find_module to use "clean" sys.path on start. In that sys.path project dirname itself appears, but it's parent directory does not. Which is required to import user application whose name is starts from project name.
I added to my project settings.py lines
{{{import os, sys
sys.path.append(os.path.dirname(os.getcwd()))}}}
This makes manage.py to see management commands added by user applications.
I think that project parent directory appending have to be done by manage.py if that directory is not in sys.path.