カスタムdjango-adminコマンドの作成—Djangoドキュメント
カスタムdjango-adminコマンドの作成
アプリケーションは、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
コマンドは、:setting: `INSTALLED_APPS` にpolls
アプリケーションを含むすべてのプロジェクトで使用できるようになります。
_private.py
モジュールは管理コマンドとして使用できません。
closepoll.py
モジュールの要件は1つだけです。つまり、 BaseCommand またはそのサブクラスの1つを拡張するクラスCommand
を定義する必要があります。
スタンドアロンスクリプト
カスタム管理コマンドは、スタンドアロンスクリプトの実行、またはUNIXcrontabまたは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()
メソッドは、1つ以上のpoll_ids
を取り、それぞれに対してpoll.opened
をFalse
に設定します。 ユーザーが存在しないポーリングを参照した場合、 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メソッドのoptionsdictパラメーターで使用できます。 add_argument
の使用法の詳細については、argparse
Pythonのドキュメントを参照してください。
カスタムコマンドラインオプションを追加できることに加えて、すべての管理コマンドは、--verbosity
や--traceback
などのいくつかのデフォルトオプションを受け入れることができます。
管理コマンドとロケール
デフォルトでは、管理コマンドは現在アクティブなロケールで実行されます。
何らかの理由で、カスタム管理コマンドをアクティブなロケールなしで実行する必要がある場合(たとえば、翻訳されたコンテンツがデータベースに挿入されないようにするため)、ハンドルの@no_translations
デコレータを使用して翻訳を非アクティブ化します。 )メソッド:
from django.core.management.base import BaseCommand, no_translations
class Command(BaseCommand):
...
@no_translations
def handle(self, *args, **options):
...
翻訳の非アクティブ化には構成済みの設定へのアクセスが必要なため、構成済みの設定なしで機能するコマンドにデコレータを使用することはできません。
コマンドのオーバーライド
Djangoは組み込みコマンドを登録し、:setting: `INSTALLED_APPS` でコマンドを逆に検索します。 検索中に、コマンド名がすでに登録されているコマンドと重複している場合、新しく検出されたコマンドが最初のコマンドをオーバーライドします。
つまり、コマンドをオーバーライドするには、新しいコマンドの名前が同じであり、そのアプリが:setting: `INSTALLED_APPS` でオーバーライドされたコマンドのアプリの前にある必要があります。
意図せずにオーバーライドされたサードパーティアプリの管理コマンドは、プロジェクトのアプリの1つで新しいコマンドを作成することで新しい名前で利用できるようになります(:setting: `INSTALLED_APPS` [でサードパーティアプリの前に注文] X247X])オーバーライドされたコマンドのCommand
をインポートします。
コマンドオブジェクト
- class BaseCommand
すべての管理コマンドが最終的に派生する基本クラス。
コマンドライン引数を解析し、それに応じて呼び出すコードを計算するすべてのメカニズムにアクセスする場合は、このクラスを使用します。 その動作を変更する必要がない場合は、そのサブクラスのいずれかを使用することを検討してください。
BaseCommand クラスをサブクラス化するには、 handle()メソッドを実装する必要があります。
属性
すべての属性は派生クラスで設定でき、 BaseCommand のサブクラスで使用できます。
- BaseCommand.help
- コマンドの簡単な説明。ユーザーがコマンド
python manage.py help <command>
を実行するとヘルプメッセージに出力されます。
- BaseCommand.missing_args_message
- コマンドで必須の位置引数が定義されている場合は、引数が欠落している場合に返されるメッセージエラーをカスタマイズできます。 デフォルトは
argparse
(「引数が少なすぎる」)によって出力されます。
- BaseCommand.output_transaction
- コマンドがSQLステートメントを出力するかどうかを示すブール値。
True
の場合、出力は自動的にBEGIN;
とCOMMIT;
でラップされます。 デフォルト値はFalse
です。
- BaseCommand.requires_migrations_checks
- ブール値;
True
の場合、ディスク上の移行のセットがデータベース内の移行と一致しない場合、コマンドは警告を出力します。 警告は、コマンドの実行を妨げるものではありません。 デフォルト値はFalse
です。
- BaseCommand.requires_system_checks
タグのリストまたはタプル。例:
[Tags.staticfiles, Tags.models]
。 選択したタグに登録されているシステムチェックは、コマンドを実行する前にエラーがチェックされます。 値'__all__'
を使用して、すべてのシステムチェックを実行する必要があることを指定できます。 デフォルト値は'__all__'
です。バージョン3.2で変更:古いバージョンでは、
requires_system_checks
属性は、タグのリストまたはタプルではなくブール値を予期していました。
- BaseCommand.style
stdout
またはstderr
に書き込むときに色付きの出力を作成するのに役立つインスタンス属性。 例えば:self.stdout.write(self.style.SUCCESS('...'))
カラーパレットを変更する方法と使用可能なスタイルを確認するには、構文の色付けを参照してください(このセクションで説明されている「ロール」の大文字バージョンを使用してください)。
コマンドの実行時に
--no-color
オプションを渡すと、すべてのself.style()
呼び出しは色なしの元の文字列を返します。
メソッド
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
インスタンスを返します。これは、Django用にいくつかカスタマイズされたArgumentParser
サブクラスです。このメソッドをオーバーライドし、
ArgumentParser
パラメーターのkwargs
を指定してsuper()
を呼び出すことにより、インスタンスをカスタマイズできます。
- BaseCommand.add_arguments(parser)
- コマンドに渡されるコマンドライン引数を処理するためのパーサー引数を追加するためのエントリポイント。 カスタムコマンドは、このメソッドをオーバーライドして、コマンドで受け入れられる定位置引数とオプション引数の両方を追加する必要があります。
BaseCommand
を直接サブクラス化する場合、super()
を呼び出す必要はありません。
- BaseCommand.get_version()
- Djangoのバージョンを返します。これは、すべての組み込みDjangoコマンドに対して正しいはずです。 ユーザー指定のコマンドは、このメソッドをオーバーライドして、独自のバージョンを返すことができます。
- BaseCommand.execute(*args, **options)
- このコマンドの実行を試み、必要に応じてシステムチェックを実行します( require_system_checks 属性によって制御されます)。 コマンドが CommandError を発生させた場合、それは傍受されてstderrに出力されます。
- BaseCommand.handle(*args, **options)
コマンドの実際のロジック。 サブクラスはこのメソッドを実装する必要があります。
stdout
に出力される文字列を返す場合があります( 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
インストールされている1つ以上のアプリケーションラベルを引数として受け取り、それぞれに対して何かを実行する管理コマンド。
サブクラスは、 handle()を実装するのではなく、 handle_app_config()を実装する必要があります。これは、アプリケーションごとに1回呼び出されます。
- AppCommand.handle_app_config(app_config, **options)
app_config
に対してコマンドのアクションを実行します。これは、コマンドラインで指定されたアプリケーションラベルに対応する AppConfig インスタンスになります。
- class LabelCommand
コマンドラインで1つ以上の任意の引数(ラベル)を受け取り、それぞれに対して何かを行う管理コマンド。
サブクラスは、 handle()を実装するのではなく、 handle_label()を実装する必要があります。これは、ラベルごとに1回呼び出されます。
- LabelCommand.label
- コマンドに渡される任意の引数を説明する文字列。 この文字列は、コマンドの使用法テキストとエラーメッセージで使用されます。 デフォルトは
'label'
です。
- LabelCommand.handle_label(label, **options)
label
に対してコマンドのアクションを実行します。これは、コマンドラインで指定された文字列になります。
コマンドの例外
- exception CommandError(returncode=1)
管理コマンドの実行中に問題が発生したことを示す例外クラス。
コマンドラインコンソールからの管理コマンドの実行中にこの例外が発生した場合、この例外はキャッチされ、適切な出力ストリーム(つまり、stderr)に適切に出力されたエラーメッセージに変換されます。 結果として、この例外を(エラーの適切な説明とともに)発生させることは、コマンドの実行で問題が発生したことを示すための好ましい方法です。 オプションのreturncode
引数を受け入れ、sys.exit()
を使用して、終了する管理コマンドの終了ステータスをカスタマイズします。
管理コマンドが call_command()を介してコードから呼び出された場合、必要に応じて例外をキャッチするのはあなた次第です。
バージョン3.1で変更: returncode
引数が追加されました。