~ubuntu-branches/ubuntu/quantal/python-django/quantal-security

« back to all changes in this revision

Viewing changes to docs/howto/custom-management-commands.txt

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2010-05-21 07:52:55 UTC
  • mfrom: (1.3.6 upstream)
  • mto: This revision was merged to the branch mainline in revision 28.
  • Revision ID: james.westby@ubuntu.com-20100521075255-ii78v1dyfmyu3uzx
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

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