Modelに入るはずでしたが、予定を変更してコマンドラインからもっと有効的にDjangoを使う方法を載せておきます。
バッチ処理というキーワードで、マニュアルとかに書いてないんですもの。。。
Djangoシステムの有効利用
Djangoフレームワークは、Webだけに限らずshellや、自分で manage.py のサブコマンドを作成して利用することもできます。
Djangoの中で、manage.pyから使用できる機能は、「Command」と呼ばれています。
Commandの作り方
Commandは、Djangoアプリケーションの中で定義しますが、ディレクトリ構成がちょっと特殊です。
特殊なディレクトリ構成と言えば、カスタムタグやフィルターがありました。あれと似たような方法です。
アプリケーションのディレクトリの下に management/commands とパッケージ用のディレクトリを作ります。
それぞれに __init__.pyを配置することを忘れずに。
その中に、sample.pyなどとして Command 用の.pyファイルを作成します。
app_name/management/commands/sample.py
# vim*:fileencoding=utf8 from django.core.management.base import BaseCommand class Command(BaseCommand): def handle(self, *args, **options): print 'call sample command.'
Commandはこんな感じの実装です。ポイントは、クラス名はCommandとしないといけないことで、一つの.pyファイルで定義できるコマンドは一つだけということになります。
自作のCommandをmanage.py経由で呼び出す
これを manage.pyから呼び出すわけですが、実行前に読み込まれているか確認できます。
python manage.py help
とすると、利用できるCommandが一覧で表示されます。この中に、sampleが入っていれば、Django側でCommandが認識されています。
表示されないときはディレクトリ構成、ファイル名、クラス名を確認して、settings.pyの INSTALLED_APPSに登録されているか確認します。
実際に呼び出すときは、syncdb や runserver似た感じで
python manage.py sample
となります。
CommandとTemplateを組み合わせる
Commandはユーティリティとしても使えますが、バッチ処理としても活用できると思います。バッチ処理で思いつくのは、集計レポート作成や定期的なメール送信など。。。 データベース上の検索結果をテキストに埋め込んだりということも多いと思います。
そこで、DjangoのTemplateを組み合わせることで、HTMLを出力している時と同じ Template システムを使ってメールとかCSVとかを出力することができます。sample.pyを少し書き換えます。
app_name/management/commands/sample.py
# vim*:fileencoding=utf8 from django.core.management.base import BaseCommand from django.template import Context, Template template_string = """ Hello {{ message }}!! """ class Command(BaseCommand): def handle(self, *args, **options): t = Template(template_string) params = { 'message': 'World' } print t.render(params)
ファイルでは無く、文字列から Templateクラスのインスタンスを作るようにしてみました。
これを manage.py経由で実行すると
と表示されるはずです。
Template上では、Webの時と同じビルトインタグが利用できるので、ループや条件分岐なども全く同じ書き方が使えます。
ファイルを分けずに利用することもできるので、知っておくと便利です。