测试gitnore
This commit is contained in:
@@ -25,43 +25,27 @@ def _get_builtin_permissions(opts):
|
||||
"""
|
||||
perms = []
|
||||
for action in opts.default_permissions:
|
||||
perms.append(
|
||||
(
|
||||
get_permission_codename(action, opts),
|
||||
"Can %s %s" % (action, opts.verbose_name_raw),
|
||||
)
|
||||
)
|
||||
perms.append((
|
||||
get_permission_codename(action, opts),
|
||||
'Can %s %s' % (action, opts.verbose_name_raw)
|
||||
))
|
||||
return perms
|
||||
|
||||
|
||||
def create_permissions(
|
||||
app_config,
|
||||
verbosity=2,
|
||||
interactive=True,
|
||||
using=DEFAULT_DB_ALIAS,
|
||||
apps=global_apps,
|
||||
**kwargs,
|
||||
):
|
||||
def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, apps=global_apps, **kwargs):
|
||||
if not app_config.models_module:
|
||||
return
|
||||
|
||||
# Ensure that contenttypes are created for this app. Needed if
|
||||
# 'django.contrib.auth' is in INSTALLED_APPS before
|
||||
# 'django.contrib.contenttypes'.
|
||||
create_contenttypes(
|
||||
app_config,
|
||||
verbosity=verbosity,
|
||||
interactive=interactive,
|
||||
using=using,
|
||||
apps=apps,
|
||||
**kwargs,
|
||||
)
|
||||
create_contenttypes(app_config, verbosity=verbosity, interactive=interactive, using=using, apps=apps, **kwargs)
|
||||
|
||||
app_label = app_config.label
|
||||
try:
|
||||
app_config = apps.get_app_config(app_label)
|
||||
ContentType = apps.get_model("contenttypes", "ContentType")
|
||||
Permission = apps.get_model("auth", "Permission")
|
||||
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||
Permission = apps.get_model('auth', 'Permission')
|
||||
except LookupError:
|
||||
return
|
||||
|
||||
@@ -76,9 +60,7 @@ def create_permissions(
|
||||
for klass in app_config.get_models():
|
||||
# Force looking up the content types in the current database
|
||||
# before creating foreign keys to them.
|
||||
ctype = ContentType.objects.db_manager(using).get_for_model(
|
||||
klass, for_concrete_model=False
|
||||
)
|
||||
ctype = ContentType.objects.db_manager(using).get_for_model(klass, for_concrete_model=False)
|
||||
|
||||
ctypes.add(ctype)
|
||||
for perm in _get_all_permissions(klass._meta):
|
||||
@@ -87,13 +69,11 @@ def create_permissions(
|
||||
# Find all the Permissions that have a content_type for a model we're
|
||||
# looking for. We don't need to check for codenames since we already have
|
||||
# a list of the ones we're going to create.
|
||||
all_perms = set(
|
||||
Permission.objects.using(using)
|
||||
.filter(
|
||||
content_type__in=ctypes,
|
||||
)
|
||||
.values_list("content_type", "codename")
|
||||
)
|
||||
all_perms = set(Permission.objects.using(using).filter(
|
||||
content_type__in=ctypes,
|
||||
).values_list(
|
||||
"content_type", "codename"
|
||||
))
|
||||
|
||||
perms = [
|
||||
Permission(codename=codename, name=name, content_type=ct)
|
||||
@@ -117,7 +97,7 @@ def get_system_username():
|
||||
# KeyError will be raised by os.getpwuid() (called by getuser())
|
||||
# if there is no corresponding entry in the /etc/passwd file
|
||||
# (a very restricted chroot environment, for example).
|
||||
return ""
|
||||
return ''
|
||||
return result
|
||||
|
||||
|
||||
@@ -137,25 +117,23 @@ def get_default_username(check_db=True, database=DEFAULT_DB_ALIAS):
|
||||
# If the User model has been swapped out, we can't make any assumptions
|
||||
# about the default user name.
|
||||
if auth_app.User._meta.swapped:
|
||||
return ""
|
||||
return ''
|
||||
|
||||
default_username = get_system_username()
|
||||
try:
|
||||
default_username = (
|
||||
unicodedata.normalize("NFKD", default_username)
|
||||
.encode("ascii", "ignore")
|
||||
.decode("ascii")
|
||||
.replace(" ", "")
|
||||
.lower()
|
||||
unicodedata.normalize('NFKD', default_username)
|
||||
.encode('ascii', 'ignore').decode('ascii')
|
||||
.replace(' ', '').lower()
|
||||
)
|
||||
except UnicodeDecodeError:
|
||||
return ""
|
||||
return ''
|
||||
|
||||
# Run the username validator
|
||||
try:
|
||||
auth_app.User._meta.get_field("username").run_validators(default_username)
|
||||
auth_app.User._meta.get_field('username').run_validators(default_username)
|
||||
except exceptions.ValidationError:
|
||||
return ""
|
||||
return ''
|
||||
|
||||
# Don't return the default username if it is already taken.
|
||||
if check_db and default_username:
|
||||
@@ -166,5 +144,5 @@ def get_default_username(check_db=True, database=DEFAULT_DB_ALIAS):
|
||||
except auth_app.User.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
return ""
|
||||
return ''
|
||||
return default_username
|
||||
|
||||
@@ -22,29 +22,25 @@ class Command(BaseCommand):
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"username",
|
||||
nargs="?",
|
||||
help=(
|
||||
"Username to change password for; by default, it's the current "
|
||||
"username."
|
||||
),
|
||||
'username', nargs='?',
|
||||
help='Username to change password for; by default, it\'s the current username.',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--database",
|
||||
'--database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Specifies the database to use. Default is "default".',
|
||||
)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
if options["username"]:
|
||||
username = options["username"]
|
||||
if options['username']:
|
||||
username = options['username']
|
||||
else:
|
||||
username = getpass.getuser()
|
||||
|
||||
try:
|
||||
u = UserModel._default_manager.using(options["database"]).get(
|
||||
**{UserModel.USERNAME_FIELD: username}
|
||||
)
|
||||
u = UserModel._default_manager.using(options['database']).get(**{
|
||||
UserModel.USERNAME_FIELD: username
|
||||
})
|
||||
except UserModel.DoesNotExist:
|
||||
raise CommandError("user '%s' does not exist" % username)
|
||||
|
||||
@@ -58,22 +54,20 @@ class Command(BaseCommand):
|
||||
p1 = self._get_pass()
|
||||
p2 = self._get_pass("Password (again): ")
|
||||
if p1 != p2:
|
||||
self.stdout.write("Passwords do not match. Please try again.")
|
||||
self.stdout.write('Passwords do not match. Please try again.')
|
||||
count += 1
|
||||
# Don't validate passwords that don't match.
|
||||
continue
|
||||
try:
|
||||
validate_password(p2, u)
|
||||
except ValidationError as err:
|
||||
self.stderr.write("\n".join(err.messages))
|
||||
self.stderr.write('\n'.join(err.messages))
|
||||
count += 1
|
||||
else:
|
||||
password_validated = True
|
||||
|
||||
if count == MAX_TRIES:
|
||||
raise CommandError(
|
||||
"Aborting password change for user '%s' after %s attempts" % (u, count)
|
||||
)
|
||||
raise CommandError("Aborting password change for user '%s' after %s attempts" % (u, count))
|
||||
|
||||
u.set_password(p1)
|
||||
u.save()
|
||||
|
||||
+69
-121
@@ -18,77 +18,69 @@ class NotRunningInTTYException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
PASSWORD_FIELD = "password"
|
||||
PASSWORD_FIELD = 'password'
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = "Used to create a superuser."
|
||||
help = 'Used to create a superuser.'
|
||||
requires_migrations_checks = True
|
||||
stealth_options = ("stdin",)
|
||||
stealth_options = ('stdin',)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.UserModel = get_user_model()
|
||||
self.username_field = self.UserModel._meta.get_field(
|
||||
self.UserModel.USERNAME_FIELD
|
||||
)
|
||||
self.username_field = self.UserModel._meta.get_field(self.UserModel.USERNAME_FIELD)
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
"--%s" % self.UserModel.USERNAME_FIELD,
|
||||
help="Specifies the login for the superuser.",
|
||||
'--%s' % self.UserModel.USERNAME_FIELD,
|
||||
help='Specifies the login for the superuser.',
|
||||
)
|
||||
parser.add_argument(
|
||||
"--noinput",
|
||||
"--no-input",
|
||||
action="store_false",
|
||||
dest="interactive",
|
||||
'--noinput', '--no-input', action='store_false', dest='interactive',
|
||||
help=(
|
||||
"Tells Django to NOT prompt the user for input of any kind. "
|
||||
"You must use --%s with --noinput, along with an option for "
|
||||
"any other required field. Superusers created with --noinput will "
|
||||
"not be able to log in until they're given a valid password."
|
||||
% self.UserModel.USERNAME_FIELD
|
||||
'Tells Django to NOT prompt the user for input of any kind. '
|
||||
'You must use --%s with --noinput, along with an option for '
|
||||
'any other required field. Superusers created with --noinput will '
|
||||
'not be able to log in until they\'re given a valid password.' %
|
||||
self.UserModel.USERNAME_FIELD
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--database",
|
||||
'--database',
|
||||
default=DEFAULT_DB_ALIAS,
|
||||
help='Specifies the database to use. Default is "default".',
|
||||
)
|
||||
for field_name in self.UserModel.REQUIRED_FIELDS:
|
||||
field = self.UserModel._meta.get_field(field_name)
|
||||
if field.many_to_many:
|
||||
if (
|
||||
field.remote_field.through
|
||||
and not field.remote_field.through._meta.auto_created
|
||||
):
|
||||
if field.remote_field.through and not field.remote_field.through._meta.auto_created:
|
||||
raise CommandError(
|
||||
"Required field '%s' specifies a many-to-many "
|
||||
"relation through model, which is not supported." % field_name
|
||||
"relation through model, which is not supported."
|
||||
% field_name
|
||||
)
|
||||
else:
|
||||
parser.add_argument(
|
||||
"--%s" % field_name,
|
||||
action="append",
|
||||
'--%s' % field_name, action='append',
|
||||
help=(
|
||||
"Specifies the %s for the superuser. Can be used "
|
||||
"multiple times." % field_name,
|
||||
'Specifies the %s for the superuser. Can be used '
|
||||
'multiple times.' % field_name,
|
||||
),
|
||||
)
|
||||
else:
|
||||
parser.add_argument(
|
||||
"--%s" % field_name,
|
||||
help="Specifies the %s for the superuser." % field_name,
|
||||
'--%s' % field_name,
|
||||
help='Specifies the %s for the superuser.' % field_name,
|
||||
)
|
||||
|
||||
def execute(self, *args, **options):
|
||||
self.stdin = options.get("stdin", sys.stdin) # Used for testing
|
||||
self.stdin = options.get('stdin', sys.stdin) # Used for testing
|
||||
return super().execute(*args, **options)
|
||||
|
||||
def handle(self, *args, **options):
|
||||
username = options[self.UserModel.USERNAME_FIELD]
|
||||
database = options["database"]
|
||||
database = options['database']
|
||||
user_data = {}
|
||||
verbose_field_name = self.username_field.verbose_name
|
||||
try:
|
||||
@@ -99,36 +91,26 @@ class Command(BaseCommand):
|
||||
# If not provided, create the user with an unusable password.
|
||||
user_data[PASSWORD_FIELD] = None
|
||||
try:
|
||||
if options["interactive"]:
|
||||
if options['interactive']:
|
||||
# Same as user_data but without many to many fields and with
|
||||
# foreign keys as fake model instances instead of raw IDs.
|
||||
fake_user_data = {}
|
||||
if hasattr(self.stdin, "isatty") and not self.stdin.isatty():
|
||||
if hasattr(self.stdin, 'isatty') and not self.stdin.isatty():
|
||||
raise NotRunningInTTYException
|
||||
default_username = get_default_username(database=database)
|
||||
if username:
|
||||
error_msg = self._validate_username(
|
||||
username, verbose_field_name, database
|
||||
)
|
||||
error_msg = self._validate_username(username, verbose_field_name, database)
|
||||
if error_msg:
|
||||
self.stderr.write(error_msg)
|
||||
username = None
|
||||
elif username == "":
|
||||
raise CommandError(
|
||||
"%s cannot be blank." % capfirst(verbose_field_name)
|
||||
)
|
||||
elif username == '':
|
||||
raise CommandError('%s cannot be blank.' % capfirst(verbose_field_name))
|
||||
# Prompt for username.
|
||||
while username is None:
|
||||
message = self._get_input_message(
|
||||
self.username_field, default_username
|
||||
)
|
||||
username = self.get_input_data(
|
||||
self.username_field, message, default_username
|
||||
)
|
||||
message = self._get_input_message(self.username_field, default_username)
|
||||
username = self.get_input_data(self.username_field, message, default_username)
|
||||
if username:
|
||||
error_msg = self._validate_username(
|
||||
username, verbose_field_name, database
|
||||
)
|
||||
error_msg = self._validate_username(username, verbose_field_name, database)
|
||||
if error_msg:
|
||||
self.stderr.write(error_msg)
|
||||
username = None
|
||||
@@ -136,15 +118,12 @@ class Command(BaseCommand):
|
||||
user_data[self.UserModel.USERNAME_FIELD] = username
|
||||
fake_user_data[self.UserModel.USERNAME_FIELD] = (
|
||||
self.username_field.remote_field.model(username)
|
||||
if self.username_field.remote_field
|
||||
else username
|
||||
if self.username_field.remote_field else username
|
||||
)
|
||||
# Prompt for required fields.
|
||||
for field_name in self.UserModel.REQUIRED_FIELDS:
|
||||
field = self.UserModel._meta.get_field(field_name)
|
||||
user_data[field_name] = options[field_name]
|
||||
if user_data[field_name] is not None:
|
||||
user_data[field_name] = field.clean(user_data[field_name], None)
|
||||
while user_data[field_name] is None:
|
||||
message = self._get_input_message(field)
|
||||
input_value = self.get_input_data(field, message)
|
||||
@@ -152,98 +131,74 @@ class Command(BaseCommand):
|
||||
if field.many_to_many and input_value:
|
||||
if not input_value.strip():
|
||||
user_data[field_name] = None
|
||||
self.stderr.write("Error: This field cannot be blank.")
|
||||
self.stderr.write('Error: This field cannot be blank.')
|
||||
continue
|
||||
user_data[field_name] = [
|
||||
pk.strip() for pk in input_value.split(",")
|
||||
]
|
||||
user_data[field_name] = [pk.strip() for pk in input_value.split(',')]
|
||||
if not field.many_to_many:
|
||||
fake_user_data[field_name] = input_value
|
||||
|
||||
if not field.many_to_many:
|
||||
fake_user_data[field_name] = user_data[field_name]
|
||||
# Wrap any foreign keys in fake model instances.
|
||||
if field.many_to_one:
|
||||
fake_user_data[field_name] = field.remote_field.model(
|
||||
user_data[field_name]
|
||||
)
|
||||
# Wrap any foreign keys in fake model instances
|
||||
if field.many_to_one:
|
||||
fake_user_data[field_name] = field.remote_field.model(input_value)
|
||||
|
||||
# Prompt for a password if the model has one.
|
||||
while PASSWORD_FIELD in user_data and user_data[PASSWORD_FIELD] is None:
|
||||
password = getpass.getpass()
|
||||
password2 = getpass.getpass("Password (again): ")
|
||||
password2 = getpass.getpass('Password (again): ')
|
||||
if password != password2:
|
||||
self.stderr.write("Error: Your passwords didn't match.")
|
||||
# Don't validate passwords that don't match.
|
||||
continue
|
||||
if password.strip() == "":
|
||||
if password.strip() == '':
|
||||
self.stderr.write("Error: Blank passwords aren't allowed.")
|
||||
# Don't validate blank passwords.
|
||||
continue
|
||||
try:
|
||||
validate_password(password2, self.UserModel(**fake_user_data))
|
||||
except exceptions.ValidationError as err:
|
||||
self.stderr.write("\n".join(err.messages))
|
||||
response = input(
|
||||
"Bypass password validation and create user anyway? [y/N]: "
|
||||
)
|
||||
if response.lower() != "y":
|
||||
self.stderr.write('\n'.join(err.messages))
|
||||
response = input('Bypass password validation and create user anyway? [y/N]: ')
|
||||
if response.lower() != 'y':
|
||||
continue
|
||||
user_data[PASSWORD_FIELD] = password
|
||||
else:
|
||||
# Non-interactive mode.
|
||||
# Use password from environment variable, if provided.
|
||||
if (
|
||||
PASSWORD_FIELD in user_data
|
||||
and "DJANGO_SUPERUSER_PASSWORD" in os.environ
|
||||
):
|
||||
user_data[PASSWORD_FIELD] = os.environ["DJANGO_SUPERUSER_PASSWORD"]
|
||||
if PASSWORD_FIELD in user_data and 'DJANGO_SUPERUSER_PASSWORD' in os.environ:
|
||||
user_data[PASSWORD_FIELD] = os.environ['DJANGO_SUPERUSER_PASSWORD']
|
||||
# Use username from environment variable, if not provided in
|
||||
# options.
|
||||
if username is None:
|
||||
username = os.environ.get(
|
||||
"DJANGO_SUPERUSER_" + self.UserModel.USERNAME_FIELD.upper()
|
||||
)
|
||||
username = os.environ.get('DJANGO_SUPERUSER_' + self.UserModel.USERNAME_FIELD.upper())
|
||||
if username is None:
|
||||
raise CommandError(
|
||||
"You must use --%s with --noinput."
|
||||
% self.UserModel.USERNAME_FIELD
|
||||
)
|
||||
raise CommandError('You must use --%s with --noinput.' % self.UserModel.USERNAME_FIELD)
|
||||
else:
|
||||
error_msg = self._validate_username(
|
||||
username, verbose_field_name, database
|
||||
)
|
||||
error_msg = self._validate_username(username, verbose_field_name, database)
|
||||
if error_msg:
|
||||
raise CommandError(error_msg)
|
||||
|
||||
user_data[self.UserModel.USERNAME_FIELD] = username
|
||||
for field_name in self.UserModel.REQUIRED_FIELDS:
|
||||
env_var = "DJANGO_SUPERUSER_" + field_name.upper()
|
||||
env_var = 'DJANGO_SUPERUSER_' + field_name.upper()
|
||||
value = options[field_name] or os.environ.get(env_var)
|
||||
if not value:
|
||||
raise CommandError(
|
||||
"You must use --%s with --noinput." % field_name
|
||||
)
|
||||
raise CommandError('You must use --%s with --noinput.' % field_name)
|
||||
field = self.UserModel._meta.get_field(field_name)
|
||||
user_data[field_name] = field.clean(value, None)
|
||||
if field.many_to_many and isinstance(user_data[field_name], str):
|
||||
user_data[field_name] = [
|
||||
pk.strip() for pk in user_data[field_name].split(",")
|
||||
]
|
||||
|
||||
self.UserModel._default_manager.db_manager(database).create_superuser(
|
||||
**user_data
|
||||
)
|
||||
if options["verbosity"] >= 1:
|
||||
self.UserModel._default_manager.db_manager(database).create_superuser(**user_data)
|
||||
if options['verbosity'] >= 1:
|
||||
self.stdout.write("Superuser created successfully.")
|
||||
except KeyboardInterrupt:
|
||||
self.stderr.write("\nOperation cancelled.")
|
||||
self.stderr.write('\nOperation cancelled.')
|
||||
sys.exit(1)
|
||||
except exceptions.ValidationError as e:
|
||||
raise CommandError("; ".join(e.messages))
|
||||
raise CommandError('; '.join(e.messages))
|
||||
except NotRunningInTTYException:
|
||||
self.stdout.write(
|
||||
"Superuser creation skipped due to not running in a TTY. "
|
||||
"You can run `manage.py createsuperuser` in your project "
|
||||
"to create one manually."
|
||||
'Superuser creation skipped due to not running in a TTY. '
|
||||
'You can run `manage.py createsuperuser` in your project '
|
||||
'to create one manually.'
|
||||
)
|
||||
|
||||
def get_input_data(self, field, message, default=None):
|
||||
@@ -252,45 +207,38 @@ class Command(BaseCommand):
|
||||
validation exceptions.
|
||||
"""
|
||||
raw_value = input(message)
|
||||
if default and raw_value == "":
|
||||
if default and raw_value == '':
|
||||
raw_value = default
|
||||
try:
|
||||
val = field.clean(raw_value, None)
|
||||
except exceptions.ValidationError as e:
|
||||
self.stderr.write("Error: %s" % "; ".join(e.messages))
|
||||
self.stderr.write("Error: %s" % '; '.join(e.messages))
|
||||
val = None
|
||||
|
||||
return val
|
||||
|
||||
def _get_input_message(self, field, default=None):
|
||||
return "%s%s%s: " % (
|
||||
return '%s%s%s: ' % (
|
||||
capfirst(field.verbose_name),
|
||||
" (leave blank to use '%s')" % default if default else "",
|
||||
" (%s.%s)"
|
||||
% (
|
||||
" (leave blank to use '%s')" % default if default else '',
|
||||
' (%s.%s)' % (
|
||||
field.remote_field.model._meta.object_name,
|
||||
field.m2m_target_field_name()
|
||||
if field.many_to_many
|
||||
else field.remote_field.field_name,
|
||||
)
|
||||
if field.remote_field
|
||||
else "",
|
||||
field.m2m_target_field_name() if field.many_to_many else field.remote_field.field_name,
|
||||
) if field.remote_field else '',
|
||||
)
|
||||
|
||||
def _validate_username(self, username, verbose_field_name, database):
|
||||
"""Validate username. If invalid, return a string error message."""
|
||||
if self.username_field.unique:
|
||||
try:
|
||||
self.UserModel._default_manager.db_manager(database).get_by_natural_key(
|
||||
username
|
||||
)
|
||||
self.UserModel._default_manager.db_manager(database).get_by_natural_key(username)
|
||||
except self.UserModel.DoesNotExist:
|
||||
pass
|
||||
else:
|
||||
return "Error: That %s is already taken." % verbose_field_name
|
||||
return 'Error: That %s is already taken.' % verbose_field_name
|
||||
if not username:
|
||||
return "%s cannot be blank." % capfirst(verbose_field_name)
|
||||
return '%s cannot be blank.' % capfirst(verbose_field_name)
|
||||
try:
|
||||
self.username_field.clean(username, None)
|
||||
except exceptions.ValidationError as e:
|
||||
return "; ".join(e.messages)
|
||||
return '; '.join(e.messages)
|
||||
|
||||
Reference in New Issue
Block a user