Dave
Dave

Reputation: 8109

What is `*args` in a Django BaseCommand handle function for?

The signature of BaseCommand.handle is handle(*args, **kwargs). The documentation example only uses the kwargs argument.

Are there cases/ways to define command arguments/options such that they will appear as positional arguments to the handle function?

Upvotes: 2

Views: 340

Answers (1)

superswellsam
superswellsam

Reputation: 333

To answer: "What is *args in a Django BaseCommand handle function for?"...

The *args is a way to define the arguments of the handle(...) method.

As far as I can tell, in the BaseCommand.handle(...), args is not connected to command line argument parsing in any way.

As an aside, using * and ** is common practice in Python when you don't know how many arguments will be passed to the method. The names (e.g. args, kwargs, options are determined by the author of the code, and can be anything.

If you want to learn more about * and ** in Python, some places to start:

To answer: "Are there cases/ways to define command arguments/options such that they will appear as positional arguments to the handle function?"...

As far as I can tell, no. Assuming you use the add_arguments(...) method, arguments from the command line will always get placed in the options dict.

To answer a question that wasn't asked, but maybe will be useful to readers: How can you get a required positional argument in the handle(...) method?

from django.core.management.base import BaseCommand

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('required_arg')
        parser.add_argument('-o', '--optional_arg')
    
    def handle(self, *args, **options):
        print(f"req: '{options['required_arg']}'; opt: '{options['optional_arg']}'")
python manage.py foo
manage.py foo: error: the following arguments are required: required_arg

python manage.py foo hello
req: 'hello'; opt: 'None'

python manage.py foo hello -o world
req: 'hello'; opt: 'world'

Upvotes: 0

Related Questions