0

I am trying to add some arguments to my django command. My command will be executing a sql query and I'd like to have an optional argument --first_row and if --first_row is specified the user must specify a second argment --last_row.

Here is what I have tried:

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

class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('--first_row', type=int)
        parser.add_argument('--last_row', type=int)

    def handle(self, *args, **options):
        import argparse
        parser = argparse.ArgumentParser()
        self.add_arguments(parser)

        start = time.time()
        args = parser.parse_args()
        if args.first_row:
            print "first row is %d" % (args.first_row)
        end = time.time()
        self.stdout.write(self.style.SUCCESS("Operation took %d seconds" % (end-start)))

But when I run my command I get this output:

manage.py > query_db --first_row 1 --last_row 5
usage: manage.py [-h] [--first_row FIRST_ROW] [--last_row LAST_ROW]
manage.py: error: unrecognized arguments: query_db

Process finished with exit code 2

What am I doing wrong?

Red Cricket
  • 9,762
  • 21
  • 81
  • 166

1 Answers1

2

You shouldn't instantiate a new ArgumentParser in your handle method. It doesn't know about the query_db argument, so you get the unrecognized arguments: query_db error.

There are some suggestions of how to handle mutually inclusive arguments on this question. You could use the first suggestion and raise an error if first_row is present in options but last_row isn't:

from django.core.management import CommandError

def add_arguments(self, parser):
    parser.add_argument('--first_row', type=int)
    parser.add_argument('--last_row', type=int)

def handle(self, *args, **options):
    if options['first_row'] is not None and options['last_row'] is None:
        raise CommandError("--last_row is required when --first_row is specified)
    ...
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • 1
    You could look at [this question](https://stackoverflow.com/questions/14117415/in-python-using-argparse-allow-only-positive-integers) about only allowing positive integers with argparse. It might be simpler to add another if-statement in the `handle` method. There might be other checks you need to add, e.g. `first_row <= last_row`. – Alasdair Mar 30 '18 at 19:03