Django management commands and verbosity

Ren and Stimpy

[update: This post has been corrected, thanks to my commenters for your feedback]

Every Django management command gets the verbosity option for free. You may recognize this:

optional arguments:
  -h, --help            show this help message and exit
  -v {0,1,2,3}, --verbosity {0,1,2,3}
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=verbose output, 3=very verbose output

We rarely use it because doing so usually means lots of if statements scattered through our code to support this. If you’re writing quick n’ dirty code, this may look familiar in your management commands:


if options.get('verbosity') == 3:
    print('hi')

In a recent Django project, I came up with a few lines of boilerplate to support the verbosity option, assuming you’re using also the logging library and not relying on print:


import logging
class Command(BaseCommand):
    def handle(self, *args, **options):
        verbosity = options.get('verbosity')
        if verbosity == 0:
            logging.getLogger('my_command').setLevel(logging.WARN)
        elif verbosity == 1:  # default
            logging.getLogger('my_command').setLevel(logging.INFO)
        elif verbosity > 1:
            logging.getLogger('my_command').setLevel(logging.DEBUG)
        if verbosity > 2:
            logging.getLogger().setLevel(logging.DEBUG)

github.com/texas/tx_mixed_beverages/blob/master/mixed_beverages/apps/receipts/management/commands/geocode.py

So what does this do?

At the default verbosity, 1, I display INFO logging statements from my command. Increasing verbosity to 2, I also display DEBUG logs from my command. And going all the way to verbosity 3, I also enable all logging statements that reach the root logger.

Go forth and log!

2 Comments

  • 2016-02-14 - 18:17 | Permalink

    You should use `verbosity = options.get(‘verbosity’)`. No `int()` needed, this is guarded by argparse.

  • Scott Sullivan
    2016-04-15 - 15:16 | Permalink

    You have a typo; you are using `=` instead of `==`.

    “`lang=python, counterexample
    if options[‘verbosity’] = 3:
    print ‘hi’
    “`

    Also, since options[‘verbosity’] contains strings, the following logic will never evaluate as `True`.

    “`lang=python, counterexample
    if options[‘verbosity’] == 3:
    print ‘hi’
    “`
    —-

    One of the following two examples would work.

    “`lang=python
    if options[‘verbosity’] == ‘3’:
    print ‘hi’
    “`

    “`lang=python
    if int(options[‘verbosity’]) == 3:
    print ‘hi’
    “`

  • Leave a Reply

    Your email address will not be published. Required fields are marked *