💭
[Django]カスタムコマンドを作る
カスタムコマンド
Djangoでは、コマンドを自作することができます。
例えば、こんな感じに。
$ python manage.py mycommand
使いどころ
例えば、Djangoアプリの中で、バッチスクリプトを定義して、それだけ以下のように実行もできます。
$ python app/batch.py
が、Djangoが提供する機能を100%使えないので、カスタムコマンドを作るのがいちばんいいと思います。(例えば通常のスクリプトで書く場合、modelなどが活用できません)
作ってみる
やることリスト
おおよそ以下の手順で作っていきます。
- startappで「sample_app」アプリを作る
-
settings.py
のINSTALLED_APPSに追加 - 「sample_app」直下に「management」フォルダを作る
- 「management」の中に「commands」フォルダを作る
- 「commands」の中に「
__init__.py
」を作る - 「commands」の中に「
mycommand.py
」を作る - 「
mycommand.py
」にdjango.core.management.base.BaseCommand
を継承したCommandクラスを作り、必要なメソッドをオーバーライドする - 「python manage.py mycommand」とすると定義したプログラムを実行できる
準備
とりあえずDjangoプロジェクトから作ってみましょう。
Linuxコマンドでフォルダやファイル作ってますけど、コマンドじゃなくても一緒です。
$ django-admin startproject project
$ cd project
$ python startapp sample_app
$ mkdir -p sample_app/management/commands
$ touch sample_app/management/commands/__init__.py
$ touch sample_app/management/commands/mycommand.py
INSTALLED_APPS = [
...
'sample_app.apps.SampleAppConfig'
]
tree
.
├── sample_app
│ ├── 省略
│ ├── management
│ │ └── commands
│ │ ├── __init__.py
│ │ └── mycommand.py
├── manage.py
└── project
こんなフォルダ構造になっていればOKです。
コマンドファイルを書いていく
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "テストコマンド"
def handle(self, *args, **options):
print('Hello World!')
ポイントは、
- BaseCommandを継承したCommandを定義すること
- Commandクラスの変数helpは
python manage.py help カスタムコマンド名
としたときに表示される説明文的なもの - handleメソッドを継承すること
- handleメソッド内に実行した処理を書く
実行してみる
もう実行できます。
$ python manage.py mycommand
Hello
$ python manage.py help mycommand
usage: manage.py mycommand [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback]
[--no-color] [--force-color] [--skip-checks]
テストコマンド
optional arguments:
-h, --help show this help message and exit
省略
意外と簡単でしたね。
【発展】コマンドライン引数を定義する
add_argumentsメソッドを書き加える
Commandクラスのadd_argumentsメソッドを加えると、コマンドライン引数を定義することができます。
class Command(BaseCommand):
help = "テストコマンド"
def handle(self, *args, **options):
print('Hello ' + options['name'])
def add_arguments(self, parser):
parser.add_argument('--name', nargs='?', default='', type=str)
ポイントは、add_argumentのキーワード引数です(デフォルト引数?)。
引数名 | 意味 |
---|---|
第一引数 | コマンドライン引数名、オプション名 |
nargs | コマンドライン引数の長さ。1つのキーワードに対して複数与えたりできる ?や+,1,2などの数の指定ができる。 |
default | 引数に与えなかった場合の初期値を示す。 |
type | strとかintとか型を指定する |
そのほか | にもたくさんあります。 |
handleメソッドで使う時は、引数optionsから取り出しましょう。
実行してみる
$ python manage.py mycommand
Hello
$ python manage.py mycommand --name zenn
Hello zenn
参考
Discussion