parts/django/docs/howto/custom-management-commands.txt
changeset 307 c6bca38c1cbf
equal deleted inserted replaced
306:5ff1fc726848 307:c6bca38c1cbf
       
     1 ====================================
       
     2 Writing custom django-admin commands
       
     3 ====================================
       
     4 
       
     5 .. versionadded:: 1.0
       
     6 
       
     7 Applications can register their own actions with ``manage.py``. For example,
       
     8 you might want to add a ``manage.py`` action for a Django app that you're
       
     9 distributing. In this document, we will be building a custom ``closepoll``
       
    10 command for the ``polls`` application from the
       
    11 :doc:`tutorial</intro/tutorial01>`.
       
    12 
       
    13 To do this, just add a ``management/commands`` directory to the application.
       
    14 Each Python module in that directory will be auto-discovered and registered as
       
    15 a command that can be executed as an action when you run ``manage.py``::
       
    16 
       
    17     polls/
       
    18         __init__.py
       
    19         models.py
       
    20         management/
       
    21             __init__.py
       
    22             commands/
       
    23                 __init__.py
       
    24                 closepoll.py
       
    25         tests.py
       
    26         views.py
       
    27 
       
    28 In this example, the ``closepoll`` command will be made available to any project
       
    29 that includes the ``polls`` application in :setting:`INSTALLED_APPS`.
       
    30 
       
    31 The ``closepoll.py`` module has only one requirement -- it must define a class
       
    32 ``Command`` that extends :class:`BaseCommand` or one of its
       
    33 :ref:`subclasses<ref-basecommand-subclasses>`.
       
    34 
       
    35 .. admonition:: Standalone scripts
       
    36 
       
    37   Custom management commands are especially useful for running standalone
       
    38   scripts or for scripts that are periodically executed from the UNIX crontab
       
    39   or from Windows scheduled tasks control panel.
       
    40 
       
    41 To implement the command, edit ``polls/management/commands/closepoll.py`` to
       
    42 look like this:
       
    43 
       
    44 .. code-block:: python
       
    45 
       
    46     from django.core.management.base import BaseCommand, CommandError
       
    47     from example.polls.models import Poll
       
    48 
       
    49     class Command(BaseCommand):
       
    50         args = '<poll_id poll_id ...>'
       
    51         help = 'Closes the specified poll for voting'
       
    52 
       
    53         def handle(self, *args, **options):
       
    54             for poll_id in args:
       
    55                 try:
       
    56                     poll = Poll.objects.get(pk=int(poll_id))
       
    57                 except Poll.DoesNotExist:
       
    58                     raise CommandError('Poll "%s" does not exist' % poll_id)
       
    59 
       
    60                 poll.opened = False
       
    61                 poll.save()
       
    62 
       
    63                 print 'Successfully closed poll "%s"' % poll_id
       
    64 
       
    65 The new custom command can be called using ``python manage.py closepoll
       
    66 <poll_id>``.
       
    67 
       
    68 The ``handle()`` method takes zero or more ``poll_ids`` and sets ``poll.opened``
       
    69 to ``False`` for each one. If the user referenced any nonexistant polls, a
       
    70 :class:`CommandError` is raised. The ``poll.opened`` attribute does not exist
       
    71 in the :doc:`tutorial</intro/tutorial01>` and was added to
       
    72 ``polls.models.Poll`` for this example.
       
    73 
       
    74 The same ``closepoll`` could be easily modified to delete a given poll instead
       
    75 of closing it by accepting additional command line options. These custom options
       
    76 must be added to :attr:`~BaseCommand.option_list` like this:
       
    77 
       
    78 .. code-block:: python
       
    79 
       
    80     from optparse import make_option
       
    81 
       
    82     class Command(BaseCommand):
       
    83         option_list = BaseCommand.option_list + (
       
    84             make_option('--delete',
       
    85                 action='store_true',
       
    86                 dest='delete',
       
    87                 default=False,
       
    88                 help='Delete poll instead of closing it'),
       
    89             )
       
    90         # ...
       
    91 
       
    92 In addition to being able to add custom command line options, all
       
    93 :doc:`management commands</ref/django-admin>` can accept some
       
    94 default options such as :djadminopt:`--verbosity` and :djadminopt:`--traceback`.
       
    95 
       
    96 Command objects
       
    97 ===============
       
    98 
       
    99 .. class:: BaseCommand
       
   100 
       
   101 The base class from which all management commands ultimately derive.
       
   102 
       
   103 Use this class if you want access to all of the mechanisms which
       
   104 parse the command-line arguments and work out what code to call in
       
   105 response; if you don't need to change any of that behavior,
       
   106 consider using one of its :ref:`subclasses<ref-basecommand-subclasses>`.
       
   107 
       
   108 Subclassing the :class:`BaseCommand` class requires that you implement the
       
   109 :meth:`~BaseCommand.handle` method.
       
   110 
       
   111 Attributes
       
   112 ----------
       
   113 
       
   114 All attributes can be set in your derived class and can be used in
       
   115 :class:`BaseCommand`'s :ref:`subclasses<ref-basecommand-subclasses>`.
       
   116 
       
   117 .. attribute:: BaseCommand.args
       
   118 
       
   119   A string listing the arguments accepted by the command,
       
   120   suitable for use in help messages; e.g., a command which takes
       
   121   a list of application names might set this to '<appname
       
   122   appname ...>'.
       
   123 
       
   124 .. attribute:: BaseCommand.can_import_settings
       
   125 
       
   126   A boolean indicating whether the command needs to be able to
       
   127   import Django settings; if ``True``, ``execute()`` will verify
       
   128   that this is possible before proceeding. Default value is
       
   129   ``True``.
       
   130 
       
   131 .. attribute:: BaseCommand.help
       
   132 
       
   133   A short description of the command, which will be printed in the
       
   134   help message when the user runs the command
       
   135   ``python manage.py help <command>``.
       
   136 
       
   137 .. attribute:: BaseCommand.option_list
       
   138 
       
   139   This is the list of ``optparse`` options which will be fed
       
   140   into the command's ``OptionParser`` for parsing arguments.
       
   141 
       
   142 .. attribute:: BaseCommand.output_transaction
       
   143 
       
   144   A boolean indicating whether the command outputs SQL
       
   145   statements; if ``True``, the output will automatically be
       
   146   wrapped with ``BEGIN;`` and ``COMMIT;``. Default value is
       
   147   ``False``.
       
   148 
       
   149 .. attribute:: BaseCommand.requires_model_validation
       
   150 
       
   151   A boolean; if ``True``, validation of installed models will be
       
   152   performed prior to executing the command. Default value is
       
   153   ``True``. To validate an individual application's models
       
   154   rather than all applications' models, call
       
   155   :meth:`~BaseCommand.validate` from :meth:`~BaseCommand.handle`.
       
   156 
       
   157 Methods
       
   158 -------
       
   159 
       
   160 :class:`BaseCommand` has a few methods that can be overridden but only
       
   161 the :meth:`~BaseCommand.handle` method must be implemented.
       
   162 
       
   163 .. admonition:: Implementing a constructor in a subclass
       
   164 
       
   165   If you implement ``__init__`` in your subclass of :class:`BaseCommand`,
       
   166   you must call :class:`BaseCommand`'s ``__init__``.
       
   167 
       
   168   .. code-block:: python
       
   169 
       
   170     class Command(BaseCommand):
       
   171         def __init__(self, *args, **kwargs):
       
   172             super(Command, self).__init__(*args, **kwargs)
       
   173             # ...
       
   174 
       
   175 .. method:: BaseCommand.get_version()
       
   176 
       
   177     Return the Django version, which should be correct for all
       
   178     built-in Django commands. User-supplied commands can
       
   179     override this method to return their own version.
       
   180 
       
   181 .. method:: BaseCommand.execute(*args, **options)
       
   182 
       
   183     Try to execute this command, performing model validation if
       
   184     needed (as controlled by the attribute
       
   185     :attr:`requires_model_validation`). If the command raises a
       
   186     :class:`CommandError`, intercept it and print it sensibly to
       
   187     stderr.
       
   188 
       
   189 .. method:: BaseCommand.handle(*args, **options)
       
   190 
       
   191     The actual logic of the command. Subclasses must implement this method.
       
   192 
       
   193 .. _ref-basecommand-subclasses:
       
   194 
       
   195 BaseCommand subclasses
       
   196 ----------------------
       
   197 
       
   198 .. class:: AppCommand
       
   199 
       
   200 A management command which takes one or more installed application
       
   201 names as arguments, and does something with each of them.
       
   202 
       
   203 Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
       
   204 :meth:`~AppCommand.handle_app`, which will be called once for each application.
       
   205 
       
   206 .. method:: AppCommand.handle_app(app, **options)
       
   207 
       
   208     Perform the command's actions for ``app``, which will be the
       
   209     Python module corresponding to an application name given on
       
   210     the command line.
       
   211 
       
   212 .. class:: LabelCommand
       
   213 
       
   214 A management command which takes one or more arbitrary arguments
       
   215 (labels) on the command line, and does something with each of
       
   216 them.
       
   217 
       
   218 Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
       
   219 :meth:`~LabelCommand.handle_label`, which will be called once for each label.
       
   220 
       
   221 .. method:: LabelCommand.handle_label(label, **options)
       
   222 
       
   223     Perform the command's actions for ``label``, which will be the
       
   224     string as given on the command line.
       
   225 
       
   226 .. class:: NoArgsCommand
       
   227 
       
   228 A command which takes no arguments on the command line.
       
   229 
       
   230 Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
       
   231 :meth:`~NoArgsCommand.handle_noargs`; :meth:`~BaseCommand.handle` itself is
       
   232 overridden to ensure no arguments are passed to the command.
       
   233 
       
   234 .. method:: NoArgsCommand.handle_noargs(**options)
       
   235 
       
   236     Perform this command's actions
       
   237 
       
   238 .. _ref-command-exceptions:
       
   239 
       
   240 Command exceptions
       
   241 ------------------
       
   242 
       
   243 .. class:: CommandError
       
   244 
       
   245 Exception class indicating a problem while executing a management
       
   246 command.
       
   247 
       
   248 If this exception is raised during the execution of a management
       
   249 command, it will be caught and turned into a nicely-printed error
       
   250 message to the appropriate output stream (i.e., stderr); as a
       
   251 result, raising this exception (with a sensible description of the
       
   252 error) is the preferred way to indicate that something has gone
       
   253 wrong in the execution of a command.