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.
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.