How to automate creating a Django super user
Tags: django, python, createsuperuser
Published: 2021-10-11 08:25:57

---
title: How to automate creating a Django super user
published: true
date: 2021-10-11 07:15:00 UTC
tags: Django,Python,createsuperuser
canonical_url: https://vuyisile.com/how-to-automate-creating-a-django-super-user/
---

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_EMAIL=test@test.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](https://stackoverflow.com/a/42491469/6229048) that addresses this very situation. To make your own management command, create a folder in your Django app and call it `management`. In `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 `createsuperuser2`.

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 `createsuperuser2.py` file:

```

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.

## Conclusion

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.