Django カスタムコマンドを実装します。素の Python でもカスタムコマンドは実装できますが、Django でカスタムコマンドを実装することにより、既存の資産(models.py や ORM)をそのまま使うことができ、素早く実装することができます。
私は、バッチ処理を Django のコマンドで実装し、それを cron で定期的に実行する方法をよくやります。
バージョン
- Python 3.6.4
- Django 2.0.3
インストール
Python, Django
Python と Django のインストールは、Python Web フレームワーク Django の環境を構築するの記事を参考にしてください。
実装
tree
$ tree . ├── app │ ├── __init__.py │ ├── apps.py │ ├── management │ │ ├── __init__.py │ │ └── commands │ │ ├── __init__.py │ │ └── hello_command.py │ ├── models.py │ └── views.py ├── command │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py └── manage.py 4 directories, 12 files $
まずはじめに最終形を確認します。Django のコマンドは、決まった場所に配置します。
app 下の management/commands がそれです。 その下にコマンドを実装し、ファイル名がmanage.py コマンドのサブコマンドになります。
上記でいうと、 hello_command がサブコマンドになります。
settings.py
INSTALLED_APPS = [ 'app.apps.AppConfig', ... ]
いつものように、INSTALLED_APPS に app を追加します。これをしないと、Django がコマンドを認識してくれません。
hello_command.py
from django.core.management import BaseCommand class Command(BaseCommand): help = 'ここにコマンドの説明を書けます。' def add_arguments(self, parser): parser.add_argument('opt1', help='必須オプション') parser.add_argument('--opt2', help='任意オプション') def handle(self, *args, **options): self.stdout.write(self.style.SUCCESS('Hello Django Command!')) self.stdout.write(options.__str__())
それでは、コマンドを実装します。
BaseCommand を継承し、ここでは2つの関数をオーバーライドしています。
add_arguments()
コマンドのオプションを実装します。引数を必要としない場合は、この関数の実装は必要ありません。
handle()
コマンドのメイン関数です。オプションは options で取得することができます。
動作確認
ヘルプの表示
$ python3.6 manage.py hello_command -h usage: manage.py hello_command [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--opt2 OPT2] opt1 ここにコマンドの説明を書けます。 positional arguments: opt1 必須オプション optional arguments: -h, --help show this help message and exit --version show program's version number and exit -v {0,1,2,3}, --verbosity {0,1,2,3} Verbosity level; 0=minimal output, 1=normal output, 2=verbose output, 3=very verbose output --settings SETTINGS The Python path to a settings module, e.g. "myproject.settings.main". If this isn't provided, the DJANGO_SETTINGS_MODULE environment variable will be used. --pythonpath PYTHONPATH A directory to add to the Python path, e.g. "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions --no-color Don't colorize the command output. --opt2 OPT2 任意オプション
-h オプションでコマンドのヘルプを表示することができます。
コマンドを実行
$ python3.6 manage.py hello_command usage: manage.py hello_command [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--opt2 OPT2] opt1 manage.py hello_command: error: the following arguments are required: opt1 $
最初に、オプションなしでコマンドを実行すると、opt1 を必須オプションにしたので、エラーになります。
$ python3.6 manage.py hello_command opt1 Hello Django Command! {'verbosity': 1, 'settings': None, 'pythonpath': None, 'traceback': False, 'no_color': False, 'opt1': 'opt1', 'opt2': None} $
次に、オプションを付けて実行すると、正常に実行します。options のなかに、opt1 が入っていることも確認できました。
まとめ
Django コマンドを実装しました。
元々は、素の Python でコマンドを実装していたのですが、Django で実装できることがわかって以来、ずっと、Django で実装しています。
素の Python でコマンドを実装すると、DB 関連やオプションが、結構大変なんですよね。
まだ Django でコマンドを実装したことがない人は、これを機会に、一度試してみてください。