Ответ
Custom Management Commands в Django — это способ расширить функциональность утилиты manage.py
для автоматизации рутинных задач, связанных с вашим проектом.
Назначение
Они идеально подходят для:
- Импорта/экспорта данных: например, загрузка данных из CSV-файла в базу данных.
- Периодических задач: выполнение регулярных операций (например, очистка старых записей), которые можно запускать через
cron
. - Административных скриптов: выполнение сложных действий, которые неудобно делать через админ-панель или shell.
Как создать команду
-
Внутри вашего Django-приложения создайте структуру каталогов:
management/commands/
.my_app/ ├── __init__.py ├── models.py ├── management/ │ ├── __init__.py │ └── commands/ │ ├── __init__.py │ └── my_command.py └── ...
-
В файле
my_command.py
создайте класс, унаследованный отBaseCommand
.
Пример простой команды:
# my_app/management/commands/my_command.py
from django.core.management.base import BaseCommand, CommandError
from my_app.models import MyModel
class Command(BaseCommand):
# Краткое описание команды, которое будет видно в `python manage.py help`
help = 'Описание моей кастомной команды'
def add_arguments(self, parser):
# Добавление позиционных и именованных аргументов
# Использует стандартный модуль Python `argparse`
parser.add_argument('model_ids', nargs='+', type=int, help='ID моделей для обработки')
parser.add_argument('--delete', action='store_true', help='Удалить объекты вместо обновления')
def handle(self, *args, **options):
# Основная логика команды
model_ids = options['model_ids']
should_delete = options['delete']
for model_id in model_ids:
try:
model = MyModel.objects.get(pk=model_id)
if should_delete:
model.delete()
self.stdout.write(self.style.SUCCESS(f'Объект {model_id} успешно удален.'))
else:
# Какая-то логика обновления
self.stdout.write(f'Объект {model_id} обработан.')
except MyModel.DoesNotExist:
raise CommandError(f'Объект с ID "{model_id}" не найден.')
self.stdout.write(self.style.SUCCESS('Команда успешно выполнена!'))
Запуск команды
Команда запускается из терминала так же, как и стандартные команды Django:
# Вызов команды с аргументами
python manage.py my_command 1 2 3
# Вызов с флагом
python manage.py my_command 1 2 --delete