2

Following the example of writing a custom django-admin command here, I've created the following custom command:

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    args = ''
    help = 'Test command'

    def handle(self, *args, **options):
        self.stdout.write("Hello World!")

Surprisingly, I receive the following stack trace:

Traceback (most recent call last):
  File "D:\My Documents\Dev\MyProject\svn\trunk\dj_project\manage.py", line 11, in <module>
    execute_manager(settings)
  File "C:\Python26\lib\site-packages\django\core\management\__init__.py", line 438, in execute_manager
    utility.execute()
  File "C:\Python26\lib\site-packages\django\core\management\__init__.py", line 379, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Python26\lib\site-packages\django\core\management\base.py", line 191, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "C:\Python26\lib\site-packages\django\core\management\base.py", line 218, in execute
    output = self.handle(*args, **options)
  File "D:\My Documents\Dev\MyProject\svn\trunk\dj_project\..\dj_project\dj_app\management\commands\mytest.py", line 8, in handle
    self.stdout.write("Hello World!")
AttributeError: 'Command' object has no attribute 'stdout'

How come? This is a very basic custom command that as far as I understand conforms to the example.

I'm using django 1.2.1

Jonathan Livni
  • 101,334
  • 104
  • 266
  • 359

3 Answers3

18

Since this is the first hit on Google I'll write another solution to another problem with the same error message: If your class Command implements __init__, it has to call __init__ of the superclass.

This will work:

from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def __init__(self, *args, **kwargs):
        super(Command, self).__init__(*args, **kwargs)
        ... do stuff

This won't work:

from django.core.management.base import BaseCommand

class Command(BaseCommand):

    def __init__(self, *args, **kwargs):
       ... do stuff
Willi Müller
  • 631
  • 1
  • 5
  • 13
5

There are two easy solutions here. The simple one is to simply convert all of your self.stdout lines to print statements instead.

That's an OK solution and you can do it.

The better solution, since self.stdout is set up in the execute() method, is to...run the execute() method.

So instead of:

Command().handle()

Do:

Command().execute()

That'll set up the self.stdout variable correctly and you'll be off and running.

mlissner
  • 17,359
  • 18
  • 106
  • 169
  • This answer should be picked as hte best answer! – wei Dec 16 '14 at 15:23
  • Thank you for this suggestion. Can anyone confirm is there any real difference between handle and execute? I have just changed my handle definition to execute and i am getting the desired result. But little concern is there any actual benefit of using handle in place of execute. – just10minutes Dec 28 '16 at 09:53
4

It looks like the mapping to self.stdout is a very new change in Django's trunk version, committed in May. If you're running the 1.2 release or earlier, this won't work - and you should be using the earlier documentation.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • I'm running django 1.2.1 so still need an answer. Will update the question. – Jonathan Livni Jul 02 '10 at 19:00
  • I don't know why my answer wasn't satisfactory. Django 1.2.1 was released on May 24, this change was made on June 6. – Daniel Roseman Jul 02 '10 at 19:22
  • 1
    @Jonathan: just replace "self.stdout.write" with "print". @Daniel I think your answer would benefit from mentioning the actual fix. But +1 because it helped me with my problem :) – Roman Starkov Oct 15 '10 at 16:29