mirror of https://github.com/django/django.git
Fixed #19725 -- Made createsuperuser handle non-ascii prompts
Thanks Michisu for the report.
This commit is contained in:
parent
fb606e10ac
commit
55c585f1c7
|
@ -11,6 +11,7 @@ from django.contrib.auth.management import get_default_username
|
|||
from django.core import exceptions
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db import DEFAULT_DB_ALIAS
|
||||
from django.utils.encoding import force_str
|
||||
from django.utils.six.moves import input
|
||||
from django.utils.text import capfirst
|
||||
|
||||
|
@ -83,8 +84,9 @@ class Command(BaseCommand):
|
|||
if not username:
|
||||
input_msg = capfirst(self.username_field.verbose_name)
|
||||
if default_username:
|
||||
input_msg += " (leave blank to use '%s')" % default_username
|
||||
raw_value = input(input_msg + ': ')
|
||||
input_msg = "%s (leave blank to use '%s')" % (
|
||||
input_msg, default_username)
|
||||
raw_value = input(force_str('%s: ' % input_msg))
|
||||
|
||||
if default_username and raw_value == '':
|
||||
raw_value = default_username
|
||||
|
@ -107,7 +109,7 @@ class Command(BaseCommand):
|
|||
field = self.UserModel._meta.get_field(field_name)
|
||||
user_data[field_name] = options.get(field_name)
|
||||
while user_data[field_name] is None:
|
||||
raw_value = input(capfirst(field.verbose_name + ': '))
|
||||
raw_value = input(force_str('%s: ' % capfirst(field.verbose_name)))
|
||||
try:
|
||||
user_data[field_name] = field.clean(raw_value, None)
|
||||
except exceptions.ValidationError as e:
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import locale
|
||||
|
||||
from django.contrib.auth import get_user_model
|
||||
|
@ -12,6 +15,37 @@ from django.test.utils import override_settings
|
|||
from django.utils.six import StringIO
|
||||
|
||||
|
||||
def mock_inputs(inputs):
|
||||
"""
|
||||
Decorator to temporarily replace input/getpass to allow interactive
|
||||
createsuperuser.
|
||||
"""
|
||||
def inner(test_func):
|
||||
def wrapped(*args):
|
||||
class mock_getpass:
|
||||
pass
|
||||
mock_getpass.getpass = staticmethod(lambda p=None: inputs['password'])
|
||||
|
||||
def mock_input(prompt):
|
||||
# prompt should be encoded in Python 2. This line will raise an
|
||||
# Exception if prompt contains unencoded non-ascii on Python 2.
|
||||
prompt = str(prompt)
|
||||
if str('leave blank to use') in prompt:
|
||||
return inputs['username']
|
||||
|
||||
old_getpass = createsuperuser.getpass
|
||||
old_input = createsuperuser.input
|
||||
createsuperuser.getpass = mock_getpass
|
||||
createsuperuser.input = mock_input
|
||||
try:
|
||||
test_func(*args)
|
||||
finally:
|
||||
createsuperuser.getpass = old_getpass
|
||||
createsuperuser.input = old_input
|
||||
return wrapped
|
||||
return inner
|
||||
|
||||
|
||||
@skipIfCustomUser
|
||||
class BasicTestCase(TestCase):
|
||||
def test_user(self):
|
||||
|
@ -103,17 +137,17 @@ class BasicTestCase(TestCase):
|
|||
self.assertEqual(u.email, 'joe2@somewhere.org')
|
||||
self.assertFalse(u.has_usable_password())
|
||||
|
||||
new_io = StringIO()
|
||||
call_command("createsuperuser",
|
||||
interactive=False,
|
||||
username="joe+admin@somewhere.org",
|
||||
email="joe@somewhere.org",
|
||||
stdout=new_io
|
||||
verbosity=0
|
||||
)
|
||||
u = User.objects.get(username="joe+admin@somewhere.org")
|
||||
self.assertEqual(u.email, 'joe@somewhere.org')
|
||||
self.assertFalse(u.has_usable_password())
|
||||
|
||||
@mock_inputs({'password': "nopasswd"})
|
||||
def test_createsuperuser_nolocale(self):
|
||||
"""
|
||||
Check that createsuperuser does not break when no locale is set. See
|
||||
|
@ -121,39 +155,47 @@ class BasicTestCase(TestCase):
|
|||
"""
|
||||
|
||||
old_getdefaultlocale = locale.getdefaultlocale
|
||||
old_getpass = createsuperuser.getpass
|
||||
try:
|
||||
# Temporarily remove locale information
|
||||
locale.getdefaultlocale = lambda: (None, None)
|
||||
|
||||
# Temporarily replace getpass to allow interactive code to be used
|
||||
# non-interactively
|
||||
class mock_getpass:
|
||||
pass
|
||||
mock_getpass.getpass = staticmethod(lambda p=None: "nopasswd")
|
||||
createsuperuser.getpass = mock_getpass
|
||||
|
||||
# Call the command in this new environment
|
||||
new_io = StringIO()
|
||||
call_command("createsuperuser",
|
||||
interactive=True,
|
||||
username="nolocale@somewhere.org",
|
||||
email="nolocale@somewhere.org",
|
||||
stdout=new_io
|
||||
verbosity=0
|
||||
)
|
||||
|
||||
except TypeError:
|
||||
self.fail("createsuperuser fails if the OS provides no information about the current locale")
|
||||
|
||||
finally:
|
||||
# Re-apply locale and getpass information
|
||||
createsuperuser.getpass = old_getpass
|
||||
# Re-apply locale information
|
||||
locale.getdefaultlocale = old_getdefaultlocale
|
||||
|
||||
# If we were successful, a user should have been created
|
||||
u = User.objects.get(username="nolocale@somewhere.org")
|
||||
self.assertEqual(u.email, 'nolocale@somewhere.org')
|
||||
|
||||
@mock_inputs({'password': "nopasswd", 'username': 'foo'})
|
||||
def test_createsuperuser_non_ascii_verbose_name(self):
|
||||
username_field = User._meta.get_field('username')
|
||||
old_verbose_name = username_field.verbose_name
|
||||
username_field.verbose_name = 'uživatel'
|
||||
new_io = StringIO()
|
||||
try:
|
||||
call_command("createsuperuser",
|
||||
interactive=True,
|
||||
email="nolocale@somewhere.org",
|
||||
stdout=new_io
|
||||
)
|
||||
finally:
|
||||
username_field.verbose_name = old_verbose_name
|
||||
|
||||
command_output = new_io.getvalue().strip()
|
||||
self.assertEqual(command_output, 'Superuser created successfully.')
|
||||
|
||||
def test_get_user_model(self):
|
||||
"The current user model can be retrieved"
|
||||
self.assertEqual(get_user_model(), User)
|
||||
|
|
Loading…
Reference in New Issue