18

我正在尝试制作一个自定义管理命令,如下面的文档所示:https ://docs.djangoproject.com/en/dev/howto/custom-management-commands/

当我尝试从我的项目目录运行命令时,我遇到以下错误:

AttributeError: 'module' object has no attribute 'Command'

这是文件:

#event_expiration.py
from django.core.management.base import BaseCommand, CommandError
from app.models import Event
import datetime

class Command(BaseCommand):
    help = 'deletes expired events'

    def handle(self, *args, **options):

        today = datetime.datetime.now()
        events = Event.objects.filter(date=datetime.date(2011,11,11))

        for e in events:
            e.delete()

        self.stdout.write('Expired events successfully deleted.')

我正在运行的命令是:

$ python manage.py event_expiration

我已确保在管理和命令文件夹中添加 event_expiration.py 文件,并且这些文件夹具有 init 文件。这些在我的一个应用程序文件夹中。

我在这里忽略了什么吗?任何帮助表示赞赏,谢谢!

编辑:

SO用户Yuji帮助我尝试调试一下,但我们仍然很难过。这是我们所做的:

首先,完整的回溯和命令:

(venv)matt@inspirion14z:~/Dropbox/PROD/ersvp.it$ python manage.py event_expiration
Traceback (most recent call last):
  File "manage.py", line 10, in <module>
    execute_from_command_line(sys.argv)
  File "/home/matt/Dropbox/PROD/ersvp.it/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line
    utility.execute()
  File "/home/matt/Dropbox/PROD/ersvp.it/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/matt/Dropbox/PROD/ersvp.it/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 261, in fetch_command
    klass = load_command_class(app_name, subcommand)
  File "/home/matt/Dropbox/PROD/ersvp.it/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 70, in load_command_class
    return module.Command()
AttributeError: 'module' object has no attribute 'Command'

要查看 django/core/management/ init .py" 的第 70 行发生了什么,我将 import pdb; pdb.set_trace() 放在文件中。

在调试模式下,我们尝试:

module.__file__ 

检查模块是否在预期的位置,并且确实如此,输出为:

'/home/matt/Dropbox/PROD/ersvp.it/app/management/commands/event_expiration.pyc'

接下来,我们尝试在 shell 中手动导入 Command:

>>> from app.management.commands.event_expiration import Command 
Traceback (most recent call last):   File "<console>", line 1, in <module> ImportError: cannot import name Command

还在挠头!

4

4 回答 4

31

我遇到了同样的问题,问题是我的命令类没有被调用Command,正如文档所说的那样。例子:

class Command(NoArgsCommand):
    # Do something here
于 2013-07-17T13:53:12.970 回答
5

你的文件结构是什么样的?它应该是这样的:

app/
    __init__.py
    management/
        __init__.py
        commands/
            __init__.py
            event_expiration.py

如果结构如上,请尝试以下操作:

python manage.py shell
>>> from app.management.commands import event_expiration
>>> dir(event_expiration)
['Account', 'BaseCommand', 'Callback', 'Command', 'CommandError', 'Comment', 'Status', 'User', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'clean_phone_number', 'csv', 'models', 'os', 're']

我已经列出了dir在我自己的管理命令上运行的纯输出。试一试,然后报告模块可用的内容。此时您可能会发现自己遇到错误,这可能有助于诊断。我怀疑导入 django 本身存在问题。我猜python manage.py shell会失败,这意味着这不是您的命令有问题,而是项目有问题。

编辑2:

check_expiration在您的输出中可见的事实dir支持我的理论,即文件夹结构在某种程度上有问题。除非您的模块中有专门命名的函数。

请执行以下操作并显示输出:

cd /path/to/app/
find .

此外,显示文件的全部内容以及event_expiration.py文件的内容management/commands/__init__.py。还要小心与制表符混合的空格作为空格。

于 2012-08-11T01:46:27.913 回答
0

直接打印查询集也会导致此错误。例如,我试图做这样的事情(只是测试,不是真正的用例):

    def handle(self, *args, **options):
       ppl = People.objects.all()
       print(ppl)

分辨率

    def handle(self, *args, **options):
       ppl = People.objects.all()
       print(str(ppl)) # Convert queryset to string

结论:在 shell 中起作用的不一定在管理命令中起作用。如果有人能指出原因会很好。

于 2020-09-10T01:05:42.050 回答
0

我通过导入常规点击模块而不是djclick

my_module/management/commands/run_thing.py

# import click  # causes the error because not setup like djclick is
import djclick as click

@click.command()
@click.option("--thing", required=True, prompt=True)
def command(thing):
    print(f"hi: {thing}"

示例运行:

./manage.py run_thing --thing 123
...
hi: 123
于 2021-09-07T15:27:45.977 回答