2 Management utility to create superusers.
7 from optparse
import make_option
9 from django
.contrib
.auth
import get_user_model
10 from django
.contrib
.auth
.management
import get_default_username
11 from django
.core
import exceptions
12 from django
.core
.management
.base
import BaseCommand
, CommandError
13 from django
.db
import DEFAULT_DB_ALIAS
14 from django
.utils
.encoding
import force_str
, force_text
15 from django
.utils
.six
.moves
import input
16 from django
.utils
.text
import capfirst
19 class Command(BaseCommand
):
21 def __init__(self
, *args
, **kwargs
):
22 # Options are defined in an __init__ method to support swapping out
23 # custom user models in tests.
24 super(Command
, self
).__init
__(*args
, **kwargs
)
25 self
.UserModel
= get_user_model()
26 self
.username_field
= self
.UserModel
._meta
.get_field(self
.UserModel
.USERNAME_FIELD
)
28 self
.option_list
= BaseCommand
.option_list
+ (
29 make_option('--%s' % self
.UserModel
.USERNAME_FIELD
, dest
=self
.UserModel
.USERNAME_FIELD
, default
=None,
30 help='Specifies the login for the superuser.'),
31 make_option('--noinput', action
='store_false', dest
='interactive', default
=True,
32 help=('Tells Django to NOT prompt the user for input of any kind. '
33 'You must use --%s with --noinput, along with an option for '
34 'any other required field. Superusers created with --noinput will '
35 ' not be able to log in until they\'re given a valid password.' %
36 self
.UserModel
.USERNAME_FIELD
)),
37 make_option('--database', action
='store', dest
='database',
38 default
=DEFAULT_DB_ALIAS
, help='Specifies the database to use. Default is "default".'),
40 make_option('--%s' % field
, dest
=field
, default
=None,
41 help='Specifies the %s for the superuser.' % field
)
42 for field
in self
.UserModel
.REQUIRED_FIELDS
45 option_list
= BaseCommand
.option_list
46 help = 'Used to create a superuser.'
48 def handle(self
, *args
, **options
):
49 username
= options
.get(self
.UserModel
.USERNAME_FIELD
, None)
50 interactive
= options
.get('interactive')
51 verbosity
= int(options
.get('verbosity', 1))
52 database
= options
.get('database')
54 # If not provided, create the user with an unusable password
58 # Do quick and dirty validation if --noinput
62 raise CommandError("You must use --%s with --noinput." %
63 self
.UserModel
.USERNAME_FIELD
)
64 username
= self
.username_field
.clean(username
, None)
66 for field_name
in self
.UserModel
.REQUIRED_FIELDS
:
67 if options
.get(field_name
):
68 field
= self
.UserModel
._meta
.get_field(field_name
)
69 user_data
[field_name
] = field
.clean(options
[field_name
], None)
71 raise CommandError("You must use --%s with --noinput." % field_name
)
72 except exceptions
.ValidationError
as e
:
73 raise CommandError('; '.join(e
.messages
))
76 # Prompt for username/password, and any other required fields.
77 # Enclose this whole thing in a try/except to trap for a
78 # keyboard interrupt and exit gracefully.
79 default_username
= get_default_username()
83 verbose_field_name
= force_text(self
.username_field
.verbose_name
)
84 while username
is None:
86 input_msg
= capfirst(verbose_field_name
)
88 input_msg
= "%s (leave blank to use '%s')" % (
89 input_msg
, default_username
)
90 raw_value
= input(force_str('%s: ' % input_msg
))
92 if default_username
and raw_value
== '':
93 raw_value
= default_username
95 username
= self
.username_field
.clean(raw_value
, None)
96 except exceptions
.ValidationError
as e
:
97 self
.stderr
.write("Error: %s" % '; '.join(e
.messages
))
101 self
.UserModel
._default
_manager
.db_manager(database
).get_by_natural_key(username
)
102 except self
.UserModel
.DoesNotExist
:
105 self
.stderr
.write("Error: That %s is already taken." %
109 for field_name
in self
.UserModel
.REQUIRED_FIELDS
:
110 field
= self
.UserModel
._meta
.get_field(field_name
)
111 user_data
[field_name
] = options
.get(field_name
)
112 while user_data
[field_name
] is None:
113 raw_value
= input(force_str('%s: ' % capfirst(force_text(field
.verbose_name
))))
115 user_data
[field_name
] = field
.clean(raw_value
, None)
116 except exceptions
.ValidationError
as e
:
117 self
.stderr
.write("Error: %s" % '; '.join(e
.messages
))
118 user_data
[field_name
] = None
121 while password
is None:
123 password
= getpass
.getpass()
124 password2
= getpass
.getpass(force_str('Password (again): '))
125 if password
!= password2
:
126 self
.stderr
.write("Error: Your passwords didn't match.")
129 if password
.strip() == '':
130 self
.stderr
.write("Error: Blank passwords aren't allowed.")
134 except KeyboardInterrupt:
135 self
.stderr
.write("\nOperation cancelled.")
138 user_data
[self
.UserModel
.USERNAME_FIELD
] = username
139 user_data
['password'] = password
140 self
.UserModel
._default
_manager
.db_manager(database
).create_superuser(**user_data
)
142 self
.stdout
.write("Superuser created successfully.")