Opened 7 years ago

Closed 6 years ago

Last modified 4 years ago

#5825 closed (fixed)

Customized actions for manage.py not working

Reported by: jdetaeye@… Owned by: nobody
Component: Core (Management commands) Version: master
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: UI/UX:

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

Download all attachments as: .zip

Change History (30)

comment:1 Changed 7 years ago by alexander.pugachev@…

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

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 Changed 7 years ago by alexander.pugachev@…

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

comment:3 Changed 7 years ago by anonymous

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

how formatting works?

comment:4 Changed 7 years ago by anonymous

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 Changed 7 years ago by anonymous

  • Owner changed from nobody to jdetaeye

Changed 7 years ago by jdetaeye@…

Patch

Changed 7 years ago by jdetaeye@…

patch

comment:6 Changed 7 years ago by anonymous

  • Has patch set

Changed 7 years ago by andrew.mcmurry@…

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 Changed 7 years ago by Simon G <dev@…>

  • Triage Stage changed from Unreviewed to Ready for checkin

comment:8 Changed 7 years ago by Simon G <dev@…>

#6013 was marked as duplicate

comment:9 Changed 7 years ago by jacob

  • Needs tests set
  • Triage Stage changed from Ready for checkin to Accepted

comment:10 Changed 7 years ago by jdetaeye

  • 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...

Changed 7 years ago by abozanich

comment:11 Changed 7 years ago by abozanich

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 Changed 7 years ago by wiswaud

  • Cc eric@… added

comment:13 Changed 7 years ago by martin

  • Cc martin@… added

comment:14 Changed 7 years ago by anonymous

  • Cc micsco@… added

comment:15 Changed 7 years ago by anonymous

  • Needs tests unset
  • Triage Stage changed from Accepted to Ready for checkin

comment:16 Changed 7 years ago by anonymous

#6128 was marked as duplicate

comment:17 Changed 7 years ago by russellm

  • milestone set to 1.0

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

comment:18 Changed 7 years ago by miracle2k

  • Cc elsdoerfer@… added

comment:19 Changed 7 years ago by edsu

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

comment:20 Changed 7 years ago by edsu

  • Cc ehs@… added

comment:21 Changed 7 years ago by russellm

  • Resolution set to fixed
  • Status changed from new to 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 Changed 7 years ago by jdetaeye

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 Changed 6 years ago by icyhandofcrap

  • Has patch unset
  • milestone changed from 1.0 to 1.1
  • Resolution fixed deleted
  • Status changed from closed to reopened
  • Triage Stage changed from Ready for checkin to 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 Changed 6 years ago by Alex

  • Resolution set to fixed
  • Status changed from reopened to 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.

Changed 6 years ago by icyhandofcrap

comment:25 Changed 4 years ago by jacob

  • milestone 1.1 deleted

Milestone 1.1 deleted

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