DjangoもPythonも初心者だけど、Djangoめっちゃ便利な関数いっぱいあるからバッチでも使いたいゾ!
やりたいこと
- Webアプリケーション向けのDjangoだけど、サイト立てずにバッチ化したい
- 引数を受け取って処理内容を分岐させたい
ディレクトリ構造
アプリケーションの直下にmanagement/commands/
のディレクトリ構造でおかないとコマンドとして認識してくれないらしい。
勿論settings.py
のINSTALLED_APPS
にアプリケーションは書いておく。
アプリケーションの構造はどうなっていてもよい。
(1プロジェクトに複数のアプリ置いてた時に同コマンド名のファイル作られてたらどうなってしまうんだろう…???)
今回はsampleBatch
コマンドを作成。
このpythonファイルの名前がそのままコマンドになる。
├── app
│ └── management
│ ├── __init__.py
│ └── commands
│ ├── __init__.py
│ └── sampleBatch.py
├── config
│ ├── __init__.py
│ ├── settings.py
│ └── urls.py
├── manage.py
└── requirements.txt
バッチクラスの中身
-
BaseCommand
を継承すること - 引数の受け取りは
add_arguments
(なくてもよい) - コマンド実行された時に動くのは
handle
- つまり1pythonファイルあたり1処理しか書けない
- (引数で処理分岐させてもいいけど、別.pyにしてコマンドを分けるべきでは???)
from django.core.management.base import BaseCommand
class Command(BaseCommand):
# [python manage.py help sampleBatch]で表示されるメッセージ
help = 'これはテスト用のコマンドバッチです'
def add_arguments(self, parser):
# コマンドライン引数を指定
parser.add_argument('-t', action='store', dest='intValue', help='【必須】1,2,3,4から好きな数字を選んでください',required=True, type=valid_type)
def handle(self, *args, **options):
try:
print('バッチが動きました: {}'.format(options['intValue']))
except Exception as e:
print(e)
def valid_type(t):
"""
引数のバリデーション
:param unicode t:
:rtype: int
"""
try:
product_type = int(t)
if product_type in [1, 2, 3, 4]:
return product_type
raise argparse.ArgumentTypeError('Choices are 1, 2, 3, 4 but {0} are given'.format(product_type))
except ValueError:
raise argparse.ArgumentTypeError('Not a valid type: {}.'.format(t))
そもそもコマンドとして認識されてるの?
ターミナルで以下のコマンドを実行して出てくるコマンド一覧に含まれていればOK。
含まれていなければどこかがおかしい…ので構造等を見直してくる。
% python manage.py help
実行する
% python manage.py sampleBatch -t 1
参考
Djangoを使ったバッチ処理の実装方法
https://www.phactory.jp/blog/django_batch/
カスタム django-admin コマンドの実装
https://docs.djangoproject.com/ja/1.10/howto/custom-management-commands/
Djangoカスタムコマンドを作成し、引数を送る
https://shotanuki.com/django%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%A0%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%92%E4%BD%9C%E6%88%90%E3%81%97%E3%80%81%E5%BC%95%E6%95%B0%E3%82%92%E9%80%81%E3%82%8B/