Opened 17 years ago

Closed 16 years ago

Last modified 13 years ago

#5825 closed (fixed)

Customized actions for manage.py not working

Reported by: jdetaeye@… 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)

usercommands.patch (4.1 KB ) - added by jdetaeye@… 17 years ago.
Patch
usercommands.2.patch (4.1 KB ) - added by jdetaeye@… 17 years ago.
patch
user_commands_path.patch (1.4 KB ) - added by andrew.mcmurry@… 17 years ago.
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.
user_command_with_test.patch (2.1 KB ) - added by abozanich 16 years ago.
managepath.diff (581 bytes ) - added by icyhandofcrap 16 years ago.

Download all attachments as: .zip

Change History (30)

comment:1 by alexander.pugachev@…, 17 years ago

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.

comment:2 by alexander.pugachev@…, 17 years ago

import os, sys
sys.path.append(os.path.dirname(os.getcwd()))

comment:3 by anonymous, 17 years ago

import os, sys 
sys.path.append(os.path.dirname(os.getcwd()))

how formatting works?

comment:4 by anonymous, 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 anonymous, 17 years ago

Owner: changed from nobody to jdetaeye

by jdetaeye@…, 17 years ago

Attachment: usercommands.patch added

Patch

by jdetaeye@…, 17 years ago

Attachment: usercommands.2.patch added

patch

comment:6 by anonymous, 17 years ago

Has patch: set

by andrew.mcmurry@…, 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 Simon G <dev@…>, 17 years ago

Triage Stage: UnreviewedReady for checkin

comment:8 by Simon G <dev@…>, 17 years ago

#6013 was marked as duplicate

comment:9 by Jacob, 17 years ago

Needs tests: set
Triage Stage: Ready for checkinAccepted

comment:10 by jdetaeye, 17 years ago

Owner: changed from jdetaeye to nobody

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 abozanich, 16 years ago

comment:11 by abozanich, 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 Éric St-Jean, 16 years ago

Cc: eric@… added

comment:13 by martin, 16 years ago

Cc: martin@… added

comment:14 by anonymous, 16 years ago

Cc: micsco@… added

comment:15 by anonymous, 16 years ago

Needs tests: unset
Triage Stage: AcceptedReady for checkin

comment:16 by anonymous, 16 years ago

#6128 was marked as duplicate

comment:17 by Russell Keith-Magee, 16 years ago

milestone: 1.0

This is a sufficiently significant problem that it warrants attention before v1.0

comment:18 by miracle2k, 16 years ago

Cc: elsdoerfer@… added

comment:19 by edsu, 16 years ago

Patch works for me. Would love to see this checked in.

comment:20 by edsu, 16 years ago

Cc: ehs@… added

comment:21 by Russell Keith-Magee, 16 years ago

Resolution: fixed
Status: newclosed

(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 jdetaeye, 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 icyhandofcrap, 16 years ago

Has patch: unset
milestone: 1.01.1
Resolution: fixed
Status: closedreopened
Triage Stage: Ready for checkinUnreviewed

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 Alex Gaynor, 16 years ago

Resolution: fixed
Status: reopenedclosed

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 icyhandofcrap, 16 years ago

Attachment: managepath.diff added

comment:25 by Jacob, 13 years ago

milestone: 1.1

Milestone 1.1 deleted

Note: See TracTickets for help on using tickets.
Back to Top