BaseCommand is the Django base class for a custom management command: a Python action run through manage.py rather than a web request. Put a command module in an app’s management/commands directory; its filename becomes the command name, while its class merely needs to inherit from BaseCommand. Django then calls handle() when the command runs. section 9.2 section 9.6
A command class can provide help text, define command-line inputs, query application data, and write results. Set help for generated --help output. Override add_arguments(parser) to register positional arguments or flags; Django creates and uses the argparse parser, then passes parsed values to handle() as options. section 9.2 section 9.3 section 9.6
Use BaseCommand’s command-friendly interfaces to keep behavior testable:
- Write normal output with self.stdout.write() and error output with self.stderr.write() instead of print(). section 9.4 section 9.6
- Raise CommandError for command errors when a friendly message is preferable to a displayed stack trace; --traceback can override that behavior. section 9.6
- Invoke commands from tests with call_command(), passing command-line-style parameters or named options and capturing stdout in StringIO. section 9.4
A musicians command
A musicians.py module defines Command(BaseCommand), sets help to “Lists registered musicians,” and implements handle(self, *args, **options). The handler loops over Musician.objects.all() and sends each formatted name to self.stdout.write(). Running python manage.py musicians prints the registered musicians; later flags can filter that query. section 9.2 section 9.3
Listing 9.2 A management command that displays the Musician objects in the database
# RiffMates/bands/management/commands/musicians.py
from django.core.management.base import BaseCommand
from bands.models import Musician
class Command(BaseCommand): #1
help = "Lists registered musicians" #2
def handle(self, *args, **options): #3
for musician in Musician.objects.all(): #4
self.stdout.write( #5
f"{musician.last_name}, {musician.first_name}"
)
Inspect the complete minimal command: inheritance supplies the command framework, handle() performs the database query, and self.stdout.write() emits each result. section 9.2
