Написание собственных django-admin
команд ¶
Приложения могут регистрировать свои действия с помощью manage.py
. Например, вы можете добавить manage.py
действие для распространяемого приложения Django. В этом документе мы создадим настраиваемую closepoll
команду для polls
приложения из
учебника .
Для этого добавьте management/commands
в приложение каталог. Django зарегистрирует manage.py
команду для каждого модуля Python в этом каталоге, имя которого не начинается с подчеркивания. Например:
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
модуля есть только одно требование - он должен определять Command
расширяемый класс
BaseCommand
или один из его
подклассов .
Автономные скрипты
Пользовательские команды управления особенно полезны для запуска автономных сценариев или для сценариев, которые периодически выполняются из crontab UNIX или из панели управления запланированными задачами 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))
Примечание
Когда вы используете команды управления и хотите обеспечить вывод на консоль, вы должны писать в self.stdout
и self.stderr
, вместо того, чтобы печатать в stdout
и stderr
напрямую. Используя эти прокси, становится намного проще протестировать вашу собственную команду. Также обратите внимание, что вам не нужно заканчивать сообщения символом новой строки, он будет добавлен автоматически, если вы не укажете ending
параметр:
self.stdout.write("Unterminated line", ending='')
Новую настраиваемую команду можно вызвать с помощью .python manage.py closepoll
<poll_ids>
handle()
Метод принимает один или более , 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
в нашем примере) доступна в параметре options dict метода handle. См. argparse
Документацию Python для получения дополнительной информации об add_argument
использовании.
Помимо возможности добавлять настраиваемые параметры командной строки, все
команды управления могут принимать некоторые параметры по умолчанию, такие как --verbosity
и --traceback
.
Команды и локали управления ¶
По умолчанию команды управления выполняются с текущим активным языковым стандартом.
Если по какой-то причине ваша настраиваемая команда управления должна выполняться без активного языкового стандарта (например, чтобы предотвратить вставку переведенного содержимого в базу данных), отключите переводы с помощью @no_translations
декоратора в вашем handle()
методе:
from django.core.management.base import BaseCommand, no_translations
class Command(BaseCommand):
...
@no_translations
def handle(self, *args, **options):
...
Поскольку для деактивации перевода требуется доступ к настроенным параметрам, декоратор не может использоваться для команд, которые работают без настроенных параметров.
Тестирование ¶
Информацию о том, как тестировать пользовательские команды управления, можно найти в документации по тестированию .
Переопределение команд ¶
Django регистрирует встроенные команды, а затем выполняет поиск команд
INSTALLED_APPS
в обратном порядке. Если во время поиска имя команды дублирует уже зарегистрированную команду, вновь обнаруженная команда отменяет первую.
Другими словами, чтобы переопределить команду, новая команда должна иметь то же имя, а ее приложение должно быть перед приложением переопределенной команды в
INSTALLED_APPS
.
Команды управления из сторонних приложений, которые были непреднамеренно переопределены, можно сделать доступными под новым именем, создав новую команду в одном из приложений вашего проекта (заказывается перед сторонним приложением в
INSTALLED_APPS
), которая импортирует Command
замененную команду.
Командные объекты ¶
-
класс
BaseCommand
¶
Базовый класс, от которого в конечном итоге наследуются все команды управления.
Используйте этот класс, если вам нужен доступ ко всем механизмам, которые анализируют аргументы командной строки и определяют, какой код вызывать в ответ; если вам не нужно изменять какое-либо из этих действий, рассмотрите возможность использования одного из его подклассов .
Создание подкласса BaseCommand
требует реализации
handle()
метода.
Атрибуты ¶
Все атрибуты могут быть установлены в производном классе и могут быть использованы в
BaseCommand
«S подклассов .
-
BaseCommand.
help
¶ Краткое описание команды, которое будет напечатано в справочном сообщении, когда пользователь запустит команду .
python manage.py help <command>
-
BaseCommand.
missing_args_message
¶ Если ваша команда определяет обязательные позиционные аргументы, вы можете настроить сообщение об ошибке, возвращаемое в случае отсутствия аргументов. По умолчанию выводится
argparse
(«слишком мало аргументов»).
-
BaseCommand.
output_transaction
¶ Логическое значение, указывающее, выводит ли команда операторы SQL; если
True
, вывод будет автоматически заключен вBEGIN;
иCOMMIT;
. Значение по умолчаниюFalse
.
-
BaseCommand.
requires_migrations_checks
¶ Логическое значение; if
True
команда выводит предупреждение, если набор миграций на диске не совпадает с миграциями в базе данных. Предупреждение не препятствует выполнению команды. Значение по умолчаниюFalse
.
-
BaseCommand.
requires_system_checks
¶ Список или кортеж тегов, например . Системные проверки, зарегистрированные в выбранных тегах, будут проверены на наличие ошибок до выполнения команды. Это значение можно использовать, чтобы указать, что все системные проверки должны быть выполнены. Значение по умолчанию .
[Tags.staticfiles, Tags.models]
'__all__'
'__all__'
Изменено в Django 3.2:В более старых версиях
requires_system_checks
атрибут ожидает логическое значение вместо списка или кортежа тегов.
-
BaseCommand.
style
¶ Атрибут экземпляра, который помогает создавать цветной вывод при записи в
stdout
илиstderr
. Например:self.stdout.write(self.style.SUCCESS('...'))
См. Раздел « Раскраска синтаксиса», чтобы узнать, как изменить цветовую палитру и увидеть доступные стили (используйте версии «ролей» в верхнем регистре, описанные в этом разделе).
Если вы передадите эту
--no-color
опцию при запуске вашей команды, всеself.style()
вызовы вернут исходную строку без цвета.
Методы ¶
BaseCommand
имеет несколько методов, которые можно переопределить, но handle()
должен быть реализован только метод.
Реализация конструктора в подклассе
Если вы реализуете __init__
в вашем подклассе BaseCommand
, вы должны называть BaseCommand
«с __init__
:
class Command(BaseCommand):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# ...
-
BaseCommand.
create_parser
( имя_программы , подкоманда , ** kwargs ) ¶ Возвращает
CommandParser
экземпляр, который являетсяArgumentParser
подклассом с некоторыми настройками для Django.Вы можете настроить экземпляр с помощью переопределения этого метода и вызова
super()
сkwargs
изArgumentParser
параметров.
-
BaseCommand.
add_arguments
( парсер ) ¶ Точка входа для добавления аргументов синтаксического анализатора для обработки аргументов командной строки, переданных команде. Пользовательские команды должны переопределить этот метод, чтобы добавить как позиционные, так и необязательные аргументы, принимаемые командой.
super()
При прямом подклассе вызов не требуетсяBaseCommand
.
-
BaseCommand.
get_version
() ¶ Возвращает версию Django, которая должна быть правильной для всех встроенных команд Django. Команды, вводимые пользователем, могут переопределять этот метод и возвращать собственную версию.
-
BaseCommand.
execute
( * аргументы , ** параметры ) ¶ Пытается выполнить эту команду, при необходимости выполняя системные проверки (в соответствии с
requires_system_checks
атрибутом). Если команда вызывает aCommandError
, она перехватывается и печатается в stderr.
Вызов команды управления в вашем коде
execute()
не следует вызывать непосредственно из вашего кода для выполнения команды. Используйте call_command()
вместо этого.
-
BaseCommand.
handle
( * аргументы , ** параметры ) ¶ Собственно логика команды. Подклассы должны реализовывать этот метод.
Он может возвращать строку, которая будет напечатана
stdout
(обернутаBEGIN;
иCOMMIT;
еслиoutput_transaction
естьTrue
).
-
BaseCommand.
check
( app_configs = None , tags = None , display_num_errors = False ) ¶ Использует фреймворк проверки системы для проверки всего проекта Django на предмет потенциальных проблем. Серьезные проблемы подняты как
CommandError
: предупреждения выводятся в stderr; второстепенные уведомления выводятся на стандартный вывод.Если
app_configs
иtags
обаNone
, все системные проверки выполняются.tags
может быть списком проверочных тегов, напримерcompatibility
илиmodels
.
BaseCommand
подклассы ¶
-
класс
AppCommand
¶
Команда управления, которая принимает в качестве аргументов одну или несколько меток установленных приложений и что-то делает с каждой из них.
Вместо реализации handle()
необходимо реализовать подклассы handle_app_config()
, которые будут вызываться один раз для каждого приложения.
-
AppCommand.
handle_app_config
( app_config , ** параметры ) ¶ Выполните действия команды для
app_config
, который будетAppConfig
экземпляром, соответствующим метке приложения, указанной в командной строке.
-
класс
LabelCommand
¶
Команда управления, которая принимает один или несколько произвольных аргументов (меток) в командной строке и что-то делает с каждым из них.
Вместо реализации handle()
необходимо реализовать подклассы
handle_label()
, которые будут вызываться один раз для каждой метки.
-
LabelCommand.
label
¶ Строка, описывающая произвольные аргументы, переданные команде. Строка используется в тексте использования и сообщениях об ошибках команды. По умолчанию
'label'
.
-
LabelCommand.
handle_label
( метка , ** варианты ) ¶ Выполните действия команды для
label
, которая будет строкой, указанной в командной строке.
Исключения команд ¶
-
исключение
CommandError
( код возврата = 1 ) ¶
Класс исключения, указывающий на проблему при выполнении команды управления.
Если это исключение возникает во время выполнения команды управления из консоли командной строки, оно будет перехвачено и преобразовано в красиво напечатанное сообщение об ошибке для соответствующего потока вывода (т. Е. Stderr); в результате создание этого исключения (с разумным описанием ошибки) является предпочтительным способом указать, что что-то пошло не так при выполнении команды. Он принимает необязательный returncode
аргумент для настройки статуса выхода для команды управления, с которой будет выполняться выход, используя sys.exit()
.
Если команда управления вызывается из кода
call_command()
, вы должны перехватить исключение, когда это необходимо.
returncode
Аргумент был добавлен.