CommandError
Исключение CommandError применяется в пользовательских командах Django для оповещения о возникновении ошибок во время их выполнения. Это исключение наследуется от стандартного Exception и используется внутри классов команд, наследующих BaseCommand. При возникновении ошибки команда завершает работу с соответствующим статусом, а сообщение об ошибке выводится в консоль. Исключение автоматически перехватывается и обрабатывается инфраструктурой Django, что позволяет избежать некрасивых traceback в продакшене.
Основное назначение CommandError - это информирование пользователя о проблемах, связанных с аргументами команды, состоянием базы данных или другими логическими ошибками. При использовании этого исключения важно передавать понятное и локализованное сообщение, которое поможет администратору разобраться в причине проблемы.
Синтаксис
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
def handle(self, *args, **options):
raise CommandError('Сообщение об ошибке')
Параметры
Исключение CommandError принимает один обязательный аргумент - строку с сообщением об ошибке. В качестве второго необязательного аргумента можно передать код возврата, который будет использован при выходе из команды. По умолчанию используется код 1.
Пример
Создадим простую команду для импорта пользователей из файла. При отсутствии файла выбрасываем исключение CommandError:
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User
import os
class Command(BaseCommand):
help = 'Import users from file'
def add_arguments(self, parser):
parser.add_argument('file_path', type=str, help='Path to user data file')
def handle(self, *args, **options):
file_path = options['file_path']
if not os.path.exists(file_path):
raise CommandError(f'File {file_path} does not exist')
with open(file_path, 'r') as f:
for line in f:
username, email = line.strip().split(',')
User.objects.create_user(username=username, email=email)
self.stdout.write(self.style.SUCCESS('Users imported successfully'))
Результат выполнения команды при указании несуществующего файла:
"Usage: manage.py import_users <file_path>"
"Error: File users.txt does not exist"
Пример
Рассмотрим более сложный пример, где проверяются аргументы команды и состояние базы данных. Команда должна принимать флаг '--force' для выполнения опасной операции:
from django.core.management.base import BaseCommand, CommandError
from myapp.models import Article
class Command(BaseCommand):
help = 'Delete all articles'
def add_arguments(self, parser):
parser.add_argument(
'--force',
action='store_true',
help='Force deletion without confirmation'
)
def handle(self, *args, **options):
article_count = Article.objects.count()
if article_count == 0:
raise CommandError('No articles to delete')
if not options['force']:
raise CommandError('Use --force to confirm deletion of all articles')
Article.objects.all().delete()
self.stdout.write(self.style.SUCCESS(f'Deleted {article_count} articles'))
Результат выполнения команды без флага '--force':
"Usage: manage.py delete_articles [--force]"
"Error: Use --force to confirm deletion of all articles"
Пример
Команда для обработки данных может проверять входные параметры и выбрасывать исключение при недопустимых значениях. Рассмотрим пример с преобразованием валют:
from django.core.management.base import BaseCommand, CommandError
from myapp.models import Product
class Command(BaseCommand):
help = 'Update product prices with currency conversion'
def add_arguments(self, parser):
parser.add_argument('--currency', type=str, default='USD', help='Target currency')
parser.add_argument('--rate', type=float, help='Conversion rate to target currency')
def handle(self, *args, **options):
currency = options['currency']
rate = options['rate']
if currency not in ['USD', 'EUR', 'RUB']:
raise CommandError(f'Unsupported currency: {currency}')
if rate is None:
raise CommandError('Rate parameter is required for currency conversion')
if rate <= 0:
raise CommandError(f'Invalid conversion rate: {rate}')
for product in Product.objects.all():
product.price_in_usd = product.price * rate
product.save()
self.stdout.write(self.style.SUCCESS(f'Prices converted to {currency}'))
Результат выполнения команды с неправильным параметром валюты:
"Usage: manage.py update_prices --currency <code> --rate <value>"
"Error: Unsupported currency: GBP"
Смотрите также
-
исключение
SystemCheckError,
которое возникает при ошибках во время системной проверки проекта -
исключение
ValidationError,
которое используется для валидации данных в формах и моделях -
исключение
DoesNotExist,
которое возникает при попытке получить несуществующий объект модели -
исключение
IntegrityError,
которое возникает при нарушении целостности данных в базе данных