python / intermediate
Snippet
Django Custom Management Commands
Custom management commands extend Django's management system, allowing you to create reusable scripts that can be executed via the command line using python manage.py. They are perfect for automated tasks like data migration, cleanup operations, or scheduled jobs. The BaseCommand class provides access to Django's environment and database, while argument parsing lets you create flexible, configurable scripts.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
from django.core.management.base import BaseCommandfrom blog.models import Postfrom django.utils import timezoneclass Command(BaseCommand):help = 'Archives posts older than 30 days'def add_arguments(self, parser):parser.add_argument('--days', type=int, default=30)parser.add_argument('--dry-run', action='store_true')def handle(self, *args, **options):days = options['days']dry_run = options['dry_run']cutoff = timezone.now() - timezone.timedelta(days=days)posts_to_archive = Post.objects.filter(published_at__lt=cutoff,is_archived=False)count = posts_to_archive.count()if dry_run:self.stdout.write(f'Would archive {count} posts')else:posts_to_archive.update(is_archived=True)self.stdout.write(self.style.SUCCESS(f'Archived {count} posts'))
django
Breakdown
1
from django.core.management.base import BaseCommand
Import BaseCommand, the foundation for all custom management commands
2
parser.add_argument('--days', type=int, default=30)
Define a named argument that accepts an integer, defaulting to 30 days
3
parser.add_argument('--dry-run', action='store_true')
Add a boolean flag that defaults to False when not provided
4
cutoff = timezone.now() - timezone.timedelta(days=days)
Calculate the date threshold by subtracting days from current time
5
posts_to_archive.update(is_archived=True)
Use update() for efficient bulk operation instead of iterating
6
self.style.SUCCESS()
Django's styling helpers colorize output in the terminal