カスタム django-admin
コマンドの実装¶
manage.py
を用いることで独自のアクションを登録する事ができます。例として、あなたが配布している Django アプリケーションに manage.py
アクションを追加したくなったとします。このドキュメントでは、このチュートリアル で作成した polls
アプリケーションに独自の closepoll
コマンドを追加します。
それを実現するには、maangement/commands
ディレクトリをアプリケーションに追加するだけで済みます。Django はディレクトリ名がアンダースコアで始まらないディレクトリ内の Python モジュール毎に manage.py
コマンドを追加します。
polls/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
_private.py
closepoll.py
tests.py
views.py
Python 2 系においては、上に示すように management
および management/commands
ディレクトリそれぞれに __init__.py
を追加しなければ実装したコマンドが検知されません。
この例では、closepoll
コマンドは polls
アプリケーションを INSTALLED_APPS
に含むプロジェクト全てで利用できるようになります。
_private.py
モジュールは管理コマンドとして利用できません。
closepoll.py
モジュールには一つだけ満たすべき要件が有ります。 – BaseCommand
クラスもしくはその サブクラス の一つを継承した Command
クラスを定義する必要が有ります。
スタンドアロンのスクリプト
カスタム管理コマンドはスタンドアロンのスクリプト、 UNIX の crontab や Windows のタスクスケジューラ管理パネルから定期的に実行されるスクリプトを処理する場合に特に有用です。
コマンドを実装するには、polls/management/commands/closepoll.py
を以下のように編集してください:
from django.core.management.base import BaseCommand, CommandError
from polls.models import Question as Poll
class Command(BaseCommand):
help = 'Closes the specified poll for voting'
def add_arguments(self, parser):
parser.add_argument('poll_id', nargs='+', type=int)
def handle(self, *args, **options):
for poll_id in options['poll_id']:
try:
poll = Poll.objects.get(pk=poll_id)
except Poll.DoesNotExist:
raise CommandError('Poll "%s" does not exist' % poll_id)
poll.opened = False
poll.save()
self.stdout.write(self.style.SUCCESS('Successfully closed poll "%s"' % poll_id))
注釈
管理コマンドを利用してコンソールへの標準出力を行いたい場合、stdout
と stderr
に直接文字列を渡すのではなく、self.stdout
および self.stderr
を利用するべきです。このようなプロキシパターンを用いることで、カスタム管理コマンドのテストをずっと簡単にする事ができます。改行文字でメッセージを終了させる必要が無い、ending
パラメータを定義しなければ自動的に改行される、事にも注意してください。:
self.stdout.write("Unterminated line", ending='')
新たに作成したカスタムコマンドは python manage.py closepoll <poll_id>
と実行する事で利用できます。
handle()
メソッドは一つ以上の poll_ids
を受け取り、それぞれに対応した poll.opened
を False
にセットします。もしコマンドの利用者が存在しない poll を指定した場合、CommandError
例外が発生します。poll.opened
属性は元の チュートリアル には存在しないので、この例では polls.models.Question
モデルに追加しました。
省略可能な引数を受け入れる¶
ここまで実装した closepoll
に対し、別途コマンドラインオプションを受け取ることで指定された投票を閉じる代わりに削除するよう機能追加する事も容易に可能です。これらのオプション機能は add_arguments()
メソッドによって以下のように追加できます。:
class Command(BaseCommand):
def add_arguments(self, parser):
# Positional arguments
parser.add_argument('poll_id', nargs='+', type=int)
# Named (optional) arguments
parser.add_argument(
'--delete',
action='store_true',
dest='delete',
default=False,
help='Delete poll instead of closing it',
)
def handle(self, *args, **options):
# ...
if options['delete']:
poll.delete()
# ...
オプション(例では delete
)は handle メソッドで辞書型変数の引数として利用可能です。add_argument
の利用についてより詳細な情報を得るには Python 公式ドキュメントの argparse
を参照してください。
独自のコマンドラインオプションを追加できるのに加え、management commands に定義された --verbosity
や --traceback
といったオプションも標準で利用できます。
管理コマンドとロケール¶
標準では、BaseCommand.execute()
メソッドは、Django に含まれる一部のコマンドが、プロジェクト全体を通じて中立な文字列の言語を必要とするタスク(例えばエンドユーザーに対するコンテンツ出力やデータベースへのデータ投入など)を実行するため、翻訳処理を無効化しています。
何らかの理由でカスタム管理コマンドから特定のロケールを利用する必要が有る場合は、I18N をサポートしているコードから提供される関数を利用している handle()
メソッド内で手動で activate と deactivate を行う必要が有ります。
from django.core.management.base import BaseCommand, CommandError
from django.utils import translation
class Command(BaseCommand):
...
can_import_settings = True
def handle(self, *args, **options):
# Activate a fixed locale, e.g. Russian
translation.activate('ru')
# Or you can activate the LANGUAGE_CODE # chosen in the settings:
from django.conf import settings
translation.activate(settings.LANGUAGE_CODE)
# Your command logic here
...
translation.deactivate()
単純に設定されたロケールをコマンドに利用させ、Django がそれを無効化しないようにしたい状況も考えられます。その状況では BaseCommand.leave_locale_alone
オプションを利用する事で望む結果を得ることができます。
ただし先に述べた状況に取り組む場合、多様なロケールでのシステム管理コマンドの実行には細心の注意を払う必要が有る事を考慮しておくべきです。すなわち以下に示す点に注意してください:
そのコマンドが実行される際は設定値
USE_I18N
が常にTrue
である事を確認してください。(これは Django を処理する動的ランタイム環境が翻訳機能を即座に無効化する事に起因する潜在的な問題の好例です)作成したコマンドとロケールが変わる事で振る舞いが変わるコードをレビューし、作成したコマンドにおいて予想される振る舞いへの影響を評価してください。
テスト¶
カスタム管理コマンドのテストに関する情報は テストに関するページ で得ることができます。
Command オブジェクト¶
全ての管理コマンドの派生元となる基底クラス。
コマンドライン引数を処理したり応答からコードの該当箇所を洗い出す機構など全てにアクセスしたい場合に利用してください。それらの振る舞いを代える必要が無ければ、:ref:`サブクラス<ref-basecommand-subclasses>`の利用を検討してください。
BaseCommand
クラスのサブクラス化には handle()
メソッドの実装が必要です。
属性¶
属性は全て派生クラスでセットでき、BaseCommand
クラスの サブクラス で利用可能です。
-
BaseCommand.
can_import_settings
¶ Django の設定値をインポート可能である必要が有るか否かを示すブーリアン値です。もし
True
であれば、execute()
は処理前にその可否を判定します。デフォルトの値は ``True。
-
BaseCommand.
help
¶ コマンドに関する短い説明、ユーザーが
python manage.py help <command>
を実行する事でヘルプメッセージとして表示されます。
-
BaseCommand.
missing_args_message
¶ 入力が必須の位置引数を定義しており、その引数が失われている場合に返すエラーメッセージを任意に設定する事ができます。デフォルトの出力は
argparse
による出力(“too few arguments”)です。
-
BaseCommand.
output_transaction
¶ A boolean indicating whether the command outputs SQL statements; if
True
, the output will automatically be wrapped withBEGIN;
andCOMMIT;
. Default value isFalse
.
-
BaseCommand.
requires_migrations_checks
¶ - New in Django 1.10.
ブーリアン値。
True
の場合、ディスク上に存在する一連のマイグレーション定義がデータベース上に保存されたマイグレーション定義とマッチしない場合に警告を出力します。この警告はコマンドの実行を停止させる物ではありません。デフォルトの値はFalse
です。
-
BaseCommand.
requires_system_checks
¶ ブーリアン値。
True
の場合、コマンド実行前に Django プロジェクト全体が潜在的な問題を抱えていないかチェックされます。デフォルトの値はTrue
です。
-
BaseCommand.
leave_locale_alone
¶ コマンド実行中にロケールを ‘en-us’ に強制的に切り替えず、設定で定義された値を使うかを指定するブーリアン値です。
デフォルトの値は
False
です。ロケールの影響を受け、かつ事実上の標準ロケールである ‘en-us’ を利用せずに翻訳も含まないデータベースの情報(例えば
django.contrib.auth
の権限の取り扱い等)を生成する場合は意図しない挙動を引き起こす可能性が有り、カスタム管理コマンドに対する本オプションの値の変更については与える影響を理解した上で決定してください。詳細は本ページ上部の Management commands and locales をご参照ください。can_import_settings
オプションがFalse
に設定されている場合は、ロケールの設定は他の設定を利用できなければならないため、このオプションをFalse
に設定できません。その状態ではCommandError
例外が発生します。
-
BaseCommand.
style
¶ stdout
やstderr
を記述した際にカラー出力を補助するインスタンス変数です。以下の利用例を参照ください:self.stdout.write(self.style.SUCCESS('...'))
カラーパレットの調整と利用可能なスタイルについては Syntax coloring を参照してください(このセクションに記述されている “roles” のアルファベットを大文字にすると利用できます)。
--no-color
オプションを渡してコマンドを実行した場合、全てのself.style()
呼び出しはオリジナルのカラー分けされていない出力を行います。
メソッド¶
BaseCommand
has a few methods that can be overridden but only
the handle()
method must be implemented.
サブクラス内でのコンストラクタの実装
BaseCommand
を継承したサブクラス内で __init__
を実装する場合、BaseCommand
の __init__
を呼び出す必要が有ります:
class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs)
# ...
-
BaseCommand.
add_arguments
(parser)[ソース]¶ コマンドに渡されたコマンドライン引数を操作するパーサーを追加するためのエントリポイントです。カスタム管理コマンドが受け取る位置引数およびオプション引数を追加するためにはこのメソッドをオーバーライドする必要が有ります。直接
BaseCommand
を継承している場合はsuper()
の呼び出しは必要有りません。
-
BaseCommand.
get_version
()[ソース]¶ Returns the Django version, which should be correct for all built-in Django commands. User-supplied commands can override this method to return their own version.
-
BaseCommand.
execute
(*args, **options)[ソース]¶ コマンドを実行し、必要とされた場合(
requires_system_checks
属性によって設定可能)システムチェックを行います。コマンドがCommandError
例外を発生させた場合は、実行を中断して stderr に出力します。
コード中での管理コマンドの呼び出し
カスタム管理コマンドを実行するためにコード中から execute()
を直接呼び出す事は避けてください。代わりに call_command()
を利用してください。
-
BaseCommand.
handle
(*args, **options)[ソース]¶ コマンドにおける実際の処理内容。サブクラスはこのメソッドを実装しなくてはならない。
stdout
に出力される Unicode 文字列(output_transaction
がTrue
の場合BEGIN;
とCOMMIT;
で囲まれている)を返す場合がある。
-
BaseCommand.
check
(app_configs=None, tags=None, display_num_errors=False)[ソース]¶ 潜在的な問題のために Django プロジェクト全体を検証するシステムチェックフレームワークを利用します。致命的な問題は
CommandError
例外を発生し、警告は stderr への出力、重要でない通知は stdout への出力となります。app_configs
およびtags
が共にNone
であった場合、全てのシステムチェックが実行されます。tags
はチェックタグ、例えばcompatibility
あるいはmodels
等、のリストとなります。
BaseCommand
のサブクラス¶
-
class
AppCommand
¶
一つ以上のインストールされたアプリケーションラベルを引数として受け取り、それぞれに対して何らかの処理を行う管理コマンド。
handle()
を実装する代わりに、サブクラスでは、アプリケーション毎に一度ずつだけ呼び出される handle_app_config()
を実装する必要が有ります。
-
AppCommand.
handle_app_config
(app_config, **options)¶ コマンドラインで渡されたアプリケーションラベル個々に対応している
AppConfig
のインスタンスであるapp_config
に応じたコマンドの処理を行います。
-
class
LabelCommand
¶
A management command which takes one or more arbitrary arguments (labels) on the command line, and does something with each of them.
Rather than implementing handle()
, subclasses must implement
handle_label()
, which will be called once for each label.
-
LabelCommand.
label
¶ コマンドに渡される任意引数について記述した文字列。この文字列はコマンドの使用法やエラーメッセージに利用します。デフォルトは
'label'
です。
-
LabelCommand.
handle_label
(label, **options)¶ コマンドラインに渡された文字列である
label
に対応したコマンドの処理を行います。
コマンドが発生させる例外¶
管理コマンド実行中に発生した問題について示した例外クラス。
コマンドラインコンソールから管理コマンドを実行中にこの例外が送出された場合、その例外は捕捉されて適切な出力ストリーム(例えば stderr 等)に整形されたエラーメッセージを表示させます。結果として、例外の送出は(エラーに関する明快な記述と併せて)コマンド実行中何らかの問題が発生した場合に状態を示す好ましい方法となります。
call_command()
を介して管理コマンドが実行された場合は、例外の捕捉をするかどうかは実装に依存します。