How to create a command in django?

2 minutes reading
django

You have used Django before, haven't you? So, you already used some Django command, it could have been makemigrations, migrate, startproject, startapp or some other. But have you ever created any? Maybe you haven't. Read on to learn how.

Create a command in django

To create a django command just create a folder called management at the same level as your manage.py file.

mkdir management

Subsequently, create a folder called commands inside this folder

cd management/
mkdir commands

Now we position ourselves inside that folder and create a file with the name of our command

cd commands/
touch tucomando.py

Inside this file we will create a class called Command that inherits from BaseCommand, with a method called handle.

# management/command/tucomando.py
from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    help = 'help text'

    def handle(self, *args, **options):
         pass

Inside the handle method we will place the code that will be executed when we use our command.

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    help = 'help text'

    def handle(self, *args, **options):
         self.stdout.write(self.style.ERROR("Texto de error"))
         self.stdout.write(self.style.WARNING("Texto de advertencia"))

To display text on the terminal we will use self.stdout.write to print text to standard output. We can select from several styles according to what we want to display.

Add arguments to the command

Django uses Python's famous argparse library to handle the arguments in its commands

Positional arguments

We can add positional arguments to the command using the add_argument method of parser.

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    help = 'help text'

    def add_arguments(self, parser):
        parser.add_argument('email', nargs='+', type=str)

We specify the name of the positional argument as the first argument, then the number of arguments it will receive. The '+' symbol states that those arguments will be placed in a list, while type is the type of values the argument will receive.

You have probably already noticed that the handle function takes *args and **options as arguments. Well, we can access the values through the options dictionary.

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    help = 'help text'

    def add_arguments(self, parser):
        parser.add_argument('email', nargs='+', type=str)

    def handle(self, *args, **options):
        # options['email'] es una lista
        send_emails(options['email'])

Optional arguments

What if I want optional arguments? Yes, that is also possible.

The Command class, through its parser, also allows us to use optional arguments.

from django.core.management.base import BaseCommand, CommandError

class Command(BaseCommand):
    help = 'help text'

    def add_arguments(self, parser):

        # Named (optional) arguments
        parser.add_argument(
            '--file',
            nargs='?',
            const='logo.svg',
            type=str,
            help='texto de ayuda',
        )

    def handle(self, *args, **options):
        if options['file'].endswith('.svg'):
            process_svg()

Now you are probably wondering what all those arguments we pass to add_argument mean.

I'll tell you right now:

** Prefix '--': tells Argparse that it is an optional argument. ** nargs: indicates the number of values our argument can receive, the '+' symbol in this case is for one or none. ** const: is the value to use if we do not specify any value for the argument.

  • type:** tells us the type of data our argument expects.
  • help: is the help text to display.

Execute the command

And to execute it? Easy; just like you would any other django command.

python manage.py tucomando
# con un argumento posicional
python managa.py tucomando email [email protected]
# o con un argumento opcional
python manage.py tuotrocomando --file=tuarchivo.svg

There, if you've read the whole thing, you now know the basics of creating django commands. But don't stop there, visit the official django documentation to learn more.

Related content