manage.py コマンドの追加
Python 札幌第3回開催直前、便乗 Django ネタ。第2回未参加なので既出かも。 manage.py にオリジナルのコマンドを追加する方法について。また、 manage.py shell インタラクティブシェルで実験したいけれど長くなりそう、というときの代わりにも使える。「アクションを追加する」も参照。
コマンド名.py というファイルを作る。雛形は以下。 BaseCommand を継承した Command という名のクラスを作る。そして handle というメソッドを作る。この中に動作を書く。
from django.core.management.base import BaseCommand class Command(BaseCommand): def handle(self, *args, **options): pass
たとえば、あるモデル spam.models.Spam のインスタンス一覧表示をしたいならこんな感じで。
from django.core.management.base import BaseCommand from spam.models import Spam class Command(BaseCommand): def handle(self, *args, **options): for spam in Spam.objects.all(): print spam
とはいえ、このような引数を必要としないシンプルなコマンドの場合は BaseCommand の代わりに NoArgsCommand を使用するのが正しい作法の模様。こちらの場合は handle_noargs メソッドを使う。
from django.core.management.base import NoArgsCommand class Command(NoArgsCommand): def handle_noargs(self, **options): pass
オプションの設定は optparse モジュールの知識があればすごく楽。知らなければ少々面倒かもしれないけれど optparse モジュールのドキュメントを参照。 Option インスタンスのリストを option_list クラス変数につくってあげれば、パーサの設定、解析などは BaseCommand がやってくれる。以下の例は django/core/management/commands/shell.py より --plain オプションを追加するというもの。
from django.core.management.base import NoArgsCommand from optparse import make_option class Command(NoArgsCommand): option_list = NoArgsCommand.option_list + ( make_option('--plain', action='store_true', dest='plain', help='Tells Django to use plain Python, not IPython.'), )
このファイルの置き場所は app_dir/management/commands の中。また、 management, commands は Python パッケージである必要がある。とりあえず空の __init__.py を置いておくとよい。 Django では設定ファイルすら Python モジュールなので、コマンドが Django アプリ(これも Python パッケージ)のサブパッケージでも違和感はない。むしろしっくりくる。