15

I created the following custom management command following this tutorial.

from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import User

from topspots.models import Notification


class Command(BaseCommand):
    help = 'Sends message to all users'

    def add_arguments(self, parser):
        parser.add_argument('message', nargs='?')

    def handle(self, *args, **options):
        message = options['message']
        users = User.objects.all()
        for user in users:
            Notification.objects.create(message=message, recipient=user)

        self.stdout.write(
            self.style.SUCCESS(
                'Message:\n\n%s\n\nsent to %d users' % (message, len(users))
            )
        )

It works exactly as I want it to, but I would like to add a confirmation step so that before the for user in users: loop you are asked if you really want to send message X to N users, and the command is aborted if you choose "no".

I assume this can be easily done because it happens with some of the built-in management commands, but it doesn't seem to cover this in the tutorial and even after some searching and looking at the source for the built-in management commands, I have not been able to figure it out on my own.

elethan
  • 16,408
  • 8
  • 64
  • 87
  • Asking for input is just basic python. An example in Django's source code can be found [here](https://github.com/django/django/blob/59afe61a970dd60df388e7cda9041ef3c0e770cb/django/db/migrations/questioner.py#L87). – knbk Aug 31 '16 at 18:49
  • Well damn. `input()` is the first thing I tried, but it didn't work the first time I tried it because of some mistake I must have made. That seems to be what I am looking for. Thank you. Feel free to post as an answer and I will accept it! – elethan Aug 31 '16 at 18:58

1 Answers1

20

You can use Python's raw_input/input function. Here's an example method from Django's source code:

from django.utils.six.moves import input

def boolean_input(question, default=None):
    result = input("%s " % question)
    if not result and default is not None:
        return default
    while len(result) < 1 or result[0].lower() not in "yn":
        result = input("Please answer yes or no: ")
    return result[0].lower() == "y"

Be sure to use the import from django.utils.six.moves if your code should be compatible with Python 2 and 3, or use raw_input() if you're on Python 2. input() on Python 2 will evaluate the input rather than converting it to a string.

knbk
  • 52,111
  • 9
  • 124
  • 122