django-admin
commands¶manage.py
を用いることで独自のアクションを登録する事ができます。例として、あなたが配布している Django アプリケーションに manage.py
アクションを追加したくなったとします。このドキュメントでは、このチュートリアル で作成した polls
アプリケーションに独自の closepoll
コマンドを追加します。
独自のコマンドを追加するためには、``management/commands``ディレクトリをアプリケーションに追加してください。Djangoは、そのディレクトリ内のアンダーバーで始まらないPythonモジュールすべてを``manage.py``コマンドに登録します。 例:
polls/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
_private.py
closepoll.py
tests.py
views.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_ids', nargs='+', type=int)
def handle(self, *args, **options):
for poll_id in options['poll_ids']:
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_ids>
と実行する事で利用できます。
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_ids', nargs='+', type=int)
# Named (optional) arguments
parser.add_argument(
'--delete',
action='store_true',
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
といったオプションも標準で利用できます。
デフォルトでは、管理コマンドは現在アクティブなロケールで実行されます。
何らかの理由でカスタム django-admin コマンドをアクティブなロケールなしで実行する必要がある場合 (たとえば、翻訳されたコンテンツがデータベースに挿入されないようにする)、handle()
method:: メソッドで@no_translationsデコレータを使用して翻訳を無効にします。
from django.core.management.base import BaseCommand, no_translations
class Command(BaseCommand):
...
@no_translations
def handle(self, *args, **options):
...
翻訳の非アクティブ化には構成設定へのアクセスが必要なので、構成設定なしで機能するコマンドにデコレータを使用することはできません。
カスタム管理コマンドのテストに関する情報は テストに関するページ で得ることができます。
Djangoは、ビルトインコマンドを読み込んだ後に INSTALLED_APPS
を逆順に検索してコマンドを登録します。この検索の際に、すでに登録済みのコマンド名と重複したコマンド名が見つかった場合、新しく見つかったコマンドで最初に見つけたコマンドをオーバーライドします。
別の言い方をすると、コマンドをオーバーライドするためには、新しいコマンドは、オーバーライドするコマンドと同じ名前でなければなりません。そして、そのアプリは、INSTALLED_APPS
で、オーバーライドするコマンドのアプリよりも前にある必要があります。
意図せずオーバーライドされたサードパーティアプリからの管理コマンドは、オーバーライドされたコマンドの Command
をインポートするプロジェクトのアプリ(INSTALLED_APPS
でサードパーティアプリの前に注文) の1つで新しいコマンドを作成することにより、新しい名前で使用可能にできます。
全ての管理コマンドの派生元となる基底クラス。
コマンドライン引数を処理したり応答からコードの該当箇所を洗い出す機構など全てにアクセスしたい場合に利用してください。それらの振る舞いを代える必要が無ければ、:ref:`サブクラス<ref-basecommand-subclasses>`の利用を検討してください。
BaseCommand
クラスのサブクラス化には handle()
メソッドの実装が必要です。
全ての属性は派生クラスでセットでき、BaseCommand
クラスの サブクラス で利用可能です。
BaseCommand.
help
¶コマンドに関する短い説明。ユーザーが python manage.py help <command>
を実行することでヘルプメッセージとして表示されます。
BaseCommand.
missing_args_message
¶入力が必須の位置引数を定義しており、その引数が失われている場合に返すエラーメッセージを任意に設定する事ができます。デフォルトの出力は argparse
による出力("too few arguments")です。
BaseCommand.
output_transaction
¶コマンドが SQL 文を出力するかどうかを決めるブール値。True
の場合、出力文が自動的に BEGIN;
と COMMIT;
で囲まれます。デフォルトの値は False
です。
BaseCommand.
requires_migrations_checks
¶Boolean。True
の場合、ディスク上に存在する一連のマイグレーション定義がデータベース上に保存されたマイグレーション定義とマッチしない場合に警告を出力します。この警告はコマンドの実行を停止させる物ではありません。デフォルトの値は False
です。
BaseCommand.
requires_system_checks
¶A list or tuple of tags, e.g. [Tags.staticfiles, Tags.models]
. System
checks registered in the chosen tags
will be checked for errors prior to executing the command. The value
'__all__'
can be used to specify that all system checks should be
performed. Default value is '__all__'
.
In older versions, the requires_system_checks
attribute expects a
boolean value instead of a list or tuple of tags.
BaseCommand.
style
¶stdout
や stderr
を記述した際にカラー出力を補助するインスタンス変数です。以下の利用例を参照ください:
self.stdout.write(self.style.SUCCESS('...'))
カラーパレットの調整と利用可能なスタイルについては Syntax coloring を参照してください (このセクションに記述されている "roles" のアルファベットを大文字にすると利用できます)。
--no-color
オプションを渡してコマンドを実行した場合、全ての self.style()
呼び出しはオリジナルのカラー分けされていない出力を行います。
BaseCommand.
suppressed_base_arguments
¶The default command options to suppress in the help output. This should be
a set of option names (e.g. '--verbosity'
). The default values for the
suppressed options are still passed.
BaseCommand
には、いくつかのオーバーライド可能なメソッドが含まれています。しかし、handle()
メソッドだけは、実装する必要が有ります。
サブクラス内でのコンストラクタの実装
BaseCommand
を継承したサブクラス内で __init__
を実装する場合、BaseCommand
の __init__
を呼び出す必要が有ります:
class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ...
BaseCommand.
create_parser
(prog_name, subcommand, **kwargs)[ソース]¶CommandParser
インスタンスを返します。これは:class:~argparse.ArgumentParser サブクラスで、Django用にいくつかカスタマイズされています。
このメソッドをオーバーライドし、 ArgumentParser
パラメータの kwargs
を使って super()
を呼び出すことでインスタンスをカスタマイズできます。
BaseCommand.
add_arguments
(parser)[ソース]¶コマンドに渡されたコマンドライン引数を操作するパーサーを追加するためのエントリポイントです。カスタム管理コマンドが受け取る位置引数およびオプション引数を追加するためにはこのメソッドをオーバーライドする必要が有ります。直接 BaseCommand
を継承している場合は super()
の呼び出しは必要有りません。
BaseCommand.
get_version
()[ソース]¶Djangoのバージョンを返します。これはすべての組み込みDjangoコマンドに対して正しいはずです。 ユーザー指定のコマンドは、このメソッドをオーバーライドして独自のバージョンを返すことができます。
BaseCommand.
execute
(*args, **options)[ソース]¶Tries to execute this command, performing system checks if needed (as
controlled by the requires_system_checks
attribute). If the command
raises a CommandError
, it's intercepted and printed to stderr
.
コード中での管理コマンドの呼び出し
カスタム管理コマンドを実行するためにコード中から execute()
を直接呼び出す事は避けてください。代わりに call_command()
を利用してください。
BaseCommand.
handle
(*args, **options)[ソース]¶コマンドにおける実際の処理内容。サブクラスはこのメソッドを実装しなくてはならない。
stdout
に出力される文字列を返すことができる (output_transaction
が True
の場合、文字列は BEGIN;
と COMMIT;
で挟まれて出力されます)。
BaseCommand.
check
(app_configs=None, tags=None, display_num_errors=False)[ソース]¶Uses the system check framework to inspect the entire Django project for
potential problems. Serious problems are raised as a CommandError
;
warnings are output to stderr
; minor notifications are output to
stdout
.
app_configs
および tags
が共に None
であった場合、全てのシステムチェックが実行されます。tags
はチェックタグ、例えば compatibility
あるいは models
等、のリストとなります。
BaseCommand
のサブクラス¶AppCommand
¶一つ以上のインストールされたアプリケーションラベルを引数として受け取り、それぞれに対して何らかの処理を行う管理コマンド。
handle()
を実装する代わりに、サブクラスでは、アプリケーション毎に一度ずつだけ呼び出される handle_app_config()
を実装する必要が有ります。
AppCommand.
handle_app_config
(app_config, **options)¶コマンドラインで渡されたアプリケーションラベル個々に対応している AppConfig
のインスタンスである app_config
に応じたコマンドの処理を行います。
LabelCommand
¶コマンドラインで1つ以上の任意の引数(ラベル)を受け取り、それぞれに対して何かを行う管理コマンド。
サブクラスは、handle()
を実装するのではなく、ラベルごとに1回呼び出される handle_label()
を実装する必要があります。
LabelCommand.
label
¶コマンドに渡される任意引数について記述した文字列。この文字列はコマンドの使用法やエラーメッセージに利用します。デフォルトは 'label'
です。
LabelCommand.
handle_label
(label, **options)¶コマンドラインに渡された文字列である label
に対応したコマンドの処理を行います。
管理コマンド実行中に発生した問題について示した例外クラス。
If this exception is raised during the execution of a management command from a
command line console, it will be caught and turned into a nicely-printed error
message to the appropriate output stream (i.e., stderr
); as a result,
raising this exception (with a sensible description of the error) is the
preferred way to indicate that something has gone wrong in the execution of a
command. It accepts the optional returncode
argument to customize the exit
status for the management command to exit with, using sys.exit()
.
call_command()
を介して管理コマンドが実行された場合は、例外の捕捉をするかどうかは実装に依存します。
2022年6月01日