Skip to main content

Administrative CLI Tools

To manage users directly from the terminal, this project provides management commands to create superusers and update user passwords. These tools support both interactive terminal sessions and automated scripts via environment variables.

Creating a Superuser

You can create a user with administrative privileges using the createsuperuser command. This command dynamically identifies the required fields based on your User model configuration.

Interactive Mode

Run the command without arguments to be prompted for the username, password, and any other required fields (e.g., email).

python manage.py createsuperuser

The command will validate your input against the User model's field constraints and password validators. If a password fails validation, you will be given the option to bypass it:

Password: 
Password (again):
The password is too similar to the username.
Bypass password validation and create user anyway? [y/N]:

Automated Creation (CI/CD)

For automated environments like CI/CD pipelines, use the --noinput flag. You must provide the username and any required fields either as CLI arguments or environment variables.

Using CLI Arguments:

python manage.py createsuperuser \
--noinput \
--username=admin_user \
--email=admin@example.com

Using Environment Variables: The command looks for environment variables prefixed with DJANGO_SUPERUSER_ followed by the uppercase field name.

export DJANGO_SUPERUSER_PASSWORD="secure_password123"
export DJANGO_SUPERUSER_USERNAME="admin_user"
export DJANGO_SUPERUSER_EMAIL="admin@example.com"

python manage.py createsuperuser --noinput

Note: If DJANGO_SUPERUSER_PASSWORD is not set in non-interactive mode, the user will be created with an unusable password and cannot log in until a password is set manually.

Changing a User Password

The changepassword command allows you to update a user's password while enforcing the project's password validation rules.

Interactive Terminal Usage

Specify the username of the account you wish to modify. If no username is provided, the command defaults to the current system user.

python manage.py changepassword my_username

The command provides a secure prompt that does not echo the password to the terminal:

Changing password for user 'my_username'
Password:
Password (again):
Password changed successfully for user 'my_username'

Programmatic Usage

You can also trigger a password change programmatically using call_command, which is useful for custom administrative scripts or tests.

from django.core.management import call_command
from io import StringIO

out = StringIO()
# Change password for 'joe' on the 'default' database
call_command("changepassword", username="joe", stdout=out)
print(out.getvalue())

Troubleshooting

TTY Requirement

The createsuperuser command requires a TTY (terminal) for interactive mode. If you attempt to run it interactively in a non-interactive environment (like a basic shell script or a Docker build step), it will raise a NotRunningInTTYException and skip creation:

Superuser creation skipped due to not running in a TTY. 
You can run `manage.py createsuperuser` in your project to create one manually.

To fix this, use the --noinput flag as described in the automated creation section.

Password Change Attempts

The changepassword command has a hard limit of 3 attempts for entering matching and valid passwords. If you fail to provide a valid, matching password three times, the command will abort:

# From django/contrib/auth/management/commands/changepassword.py
MAX_TRIES = 3
# ... logic to track attempts ...
if count == MAX_TRIES:
raise CommandError(
"Aborting password change for user '%s' after %s attempts" % (u, count)
)

Database Selection

Both commands support the --database flag if your project uses multiple databases.

python manage.py createsuperuser --database=replica_db
python manage.py changepassword my_user --database=replica_db