Setting up a Django super user may be a requirement in your test setup code. The commands used to create users are interactive by default and unfortunately do not allow you to pass in the user’s password as an argument or a flag on the command line. This is a security measure, but it isn’t great for test code. In this post, I will show you two ways of getting around this limitation through the use of environment variables and using a custom management command.
Using environment variables
One way to automate creating a super user is to run the
createsuperuser command in a non interactive way. To do this, run it with the
--no-input flag. This forces it to look for user credentials in the environment variables. To set the user credentials as environment variables in Linux, use the
export command. Once the username and password variables have been set, run the createsuperuser command with the
--no-input flag like this:
✗ export DJANGO_SUPERUSER_EMAILemail@example.com ✗ export DJANGO_SUPERUSER_PASSWORD=testpass1234 ✗ python manage.py createsuperuser --no-input Superuser created successfully.
The steps for setting environment variables will depend on your operating system and tool you’re using. The above is very useful when running tests in Linux docker containers.
Creating a custom management command
An alternative approach to the above is to create your own version of
createsuperuser command that takes a password flag. I found a Stackoverflow answer that addresses this very situation. To make your own management command, create a folder in your Django app and call it
management folder add a
__init__.py file to turn the folder into into a package. Create a subfolder called
commands in the
management directory. Add an
__init__.py file in the
commands folder as well and create a python file that’ll contain the code for your custom
createsuperuser action. You can name it
At this point, your directory structure should look something like this:
management ├── __init__.py └── commands ├── __init__.py └── createsuperuser2.py 1 directory, 3 files
Add the following to the
from django.contrib.auth.management.commands import createsuperuser from django.core.management import CommandError class Command(createsuperuser.Command): help = "Create a superuser, and allow password to be provided" def add_arguments(self, parser): super(Command, self).add_arguments(parser) parser.add_argument( "--password", dest="password", default=None, help="Specifies the password for the superuser.", ) parser.add_argument( "--preserve", dest="preserve", default=False, action="store_true", help="Exit normally if the user already exists.", ) def handle(self, *args, **options): password = options.get("password") username = options.get("username") database = options.get("database") if password and not username: raise CommandError("--username is required if specifying --password") if username and options.get("preserve"): exists = ( self.UserModel._default_manager.db_manager(database) .filter(username=username) .exists() ) if exists: self.stdout.write("User exists, exiting normally due to --preserve") return super(Command, self).handle(*args, **options) if password: user = self.UserModel._default_manager.db_manager(database).get( username=username ) user.set_password(password) user.save()
The code above subclasses the
createsuperuser command and allows you to set and update the password using a commandline flag. Note however that this code will only work for standard User models. If your code uses a custom user model with a username field that is different from the traditional
username, you will need to modify the script above to use the correct username field you’re using in your project. Save the file. To run it, do the following:
python manage.py createsuperuser2 --username admin2 --password mysecretadminpassword
If everything went well, a new user will be created.
The methods shown above are great for automating creating a super user in a non interactive way. It is important to note that passing a password as a part of the command is not safe as it will be visible in the process list. This means that the examples shown above should only be used in test systems for dummy users that won’t have access to real or sensitive information. Thanks for reading.