Использование management commands в Django

Создание собственных команд в Django

В этом руководстве рассмотрим как создавать пользовательские команды под фреймворк Django.

Введение

Мы пользуемся командами с тех пор, как только создали проект или приложение, а также в момент запуска сервера разработки. Команды для выполнения этих операций (startproject, startapp и runserver), вероятно самые популярные, но их гораздо больше, и мы также можем написать любую другую команду под собственные нужды.

Список команд по умолчанию доступных в нашем проекте, мы можем увидеть, запустив команду без параметров:

python3 manage.py

Или мы можем воспользоваться вторым способом

python3 manage.py help

Это список всех доступных команд по умолчанию:

Использование management commands в Django

А еще мы можем получить помощь для конкретной команды выполнив код:

python3 manage.py help команда

Где команда это название команды, с которой мы хотим познакомиться.

Когда необходимо создавать команду

Создание новых команд происходит, когда существующие команды не решают потребностей нашего проекта, и нам нужно сделать задачу, выполняемую время от времени (Задачи для планировщика, импорт данных из CSV и т.д.) либо автоматически, либо вручную.

Например, если какое-либо предприятие имеет систему управления персоналом, которому нужно оплачивать заработную плату, то нам нужно создать команду pay, имеющую логику производить оплату всем работникам компании.

Создание новой команды

Мы начнем работу с написания простой базовой команды. Все команды должны храниться внутри папки вашего проекта appname/management/commands/, если у вас отсутствуют эти директории, их необходимо создать.

Название будет присвоено такое же, как и у файла в котором она записана. То-есть, создав модуль под названием welcome.py, чтобы в дальнейшем выполнить эту команду необходимо ввести:

python3 manage.py welcome

Давайте проинспектируем содержимое файла welcome.py:

Использование management commands в Django

Команды должны наследовать от класса BaseCommand, и класс должен обязательно называться Command, так как Django будет искать по этому имени. Если мы назовем класс с другим именем, то при выполнении команды мы получим ошибку.

В атрибут help мы помещаем текст, который будет описывать, что команда делает, и именно этот текст будет показан при выполнении команды python3 manage.py help <command>. Код команды должен быть определен внутри метода handle.

Использование аргументов

Если вы читаете данную статью, скорее всего, вы создали хотя бы один проект с помощью Django, поэтому знакомы с командой startproject. Команда startproject имеет обязательный аргумент имя проекта. Пользовательские команды, также могут принимать аргументы.
Команды принимают два типа аргументов: именованные и позиционные.

Именованные аргументы это аргументы с префиксом ‘-‘ или ‘—‘ и не имеет значения, в каком порядке они будут передаваться команде.

Позиционные аргументы не имеют префикса и должны передаваться в том же порядке, в котором они заданы.

Аргументы в командах обрабатываются стандартной библиотекой Python argparse, поэтому обязаны удовлетворять ее спецификациям. Метод, называемый add_arguments, должен быть добавлен в команды, чтобы разрешить использование аргументов в пользовательской команде.

Использование management commands в Django

Аргумент parser является экземпляром argparse, поэтому все операции в этой библиотеке доступны и разрешены.

В случае именованных аргументов мы можем поместить «псевдонимы».

В приведенном выше примере аргумент может быть указан как «-l» или «—lastname».

Выполнение команды с аргументами, как и в предыдущем примере, производится следующим образом:

python3 manage.py welcome Egor --lastname Egorov

Аргументы со значениями по умолчанию

Для упрощения работы хочется, чтобы простой передачи аргумента было достаточно, для понимания, что делать в дальнейшем.

Например, аргумент —noreload команды runserver не требует передачи значения аргумента, так как он имеет значение по умолчанию, в данном случае значение является булевым. Если этот аргумент присутствует, значит, он имеет значение True, в противном случае это будет False. Для того чтобы создать аргумент со значением по умолчанию, при вызове метода add_argument, нам нужно добавить параметр action.

Значение параметра action будет зависеть от типа и значения по умолчанию. Если вы хотите, чтобы аргумент был булевым, то-есть при его присутствии, он должен быть True или False, он должен иметь значение store_true или store_false соответственно:

parser.add_argument('--noreload', action='store_true', help='…')

Аргументы также могут быть постоянными или делать действительно интересные вещи. Если вы обратитесь к официальной документации argparse, вы можете знать все, что можно сделать с помощью параметра action. Это пример того, как мы можем хранить константу по умолчанию:

parser.add_argument('--foo', action='store_const', const=42)

Списки аргументов

Часто мы не знаем, сколько данных будет передано нам в качестве аргумента в команду. Для решения этой проблемы существуют списки параметров, где мы можем получить список значений только с одним параметром.

Допустим, вы создаете команду для удаления пользователей, но хотите, чтобы эта команда давала возможность удалять сразу несколько пользователей. Это один из тех случаев, когда полезно использовать список аргументов.

Для создания списка необходимо добавить параметры nargs=’+’, и указать тип при вызове метода add_argument. В случае с типом параметра это может быть любой тип, принятый argparse.

Использование management commands в Django

Вышеуказанная команда выполняется следующим образом:

python3 manage.py remove_employee 10 9 8 7 6 5

Печать текста

Печать текста на стандартном выводе Python из команды выполняется несколько иначе, чем печать чего-либо в другом месте приложения. Вместо использования функции печати мы используем потоки stdout для стандартного вывода и stderr для ошибок. И stdout, и stderr являются атрибутами BaseCommand, поэтому мы можем использовать их следующим образом:

self.stderr.write('error')
self.stdout.write('normal')

Также мы можем придать тексту цвет, используя style атрибуты. Официальная документация объясняет роль каждого из этих цветов.

Вывод

Команды являются идеальным механизмом для создания отчетов, задач обслуживания, среди прочих операций, которые периодически повторяются либо вручную, либо через запланированные задачи. Передача аргументов часто является одной из самых сложных задач при создании команд с большим количеством аргументов, а официальная документация argparse часто является идеальным местом для решения этой проблемы.

Официальная документация Django по созданию команд также является отличным ресурсом для просмотра.

Егор Егоров

Программирую на Python с 2017 года. Люблю создавать контент, который помогает людям понять сложные вещи. Не представляю жизнь без непрерывного цикла обучения, спорта и чувства юмора.

Ссылка на мой github есть в шапке. Залетай.

Оцените автора
Егоров Егор
Добавить комментарий

  1. Dmitrij

    Спасибо большое, очень доступно и подробно объяснили. Ни как не мог победить дз) теперь думаю справлюсь.

    Ответить
    1. Егор Егоров автор

      хорошо что помогло)

      Ответить
  2. Дмитрий

    Спасибо, полезная статья!
    Было бы еще неплохо узнать как запустить команду при дефолтной работе сервера (т.е не на отладочном сервере). И не через вьюху, а сразу чтобы дефолтно команда работала.

    Ответить
    1. Егор Егоров автор

      привет, Дмитрий! не совсем понятно, что ты хочешь, сразу чтобы жефолтно работала это как понять?

      чтобы эта команда запускалась и работала в фоне?

      Ответить