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