How to automate createsuperuser on django?

How to automate createsuperuser on django?

I want to auto run manage.py createsuperuser on django but it seams that there is no way of setting a default password.
How can I get this? It has to be independent on the django database.

Solutions/Answers:

Answer 1:

If you reference User directly, your code will not work in projects where the AUTH_USER_MODEL setting has been changed to a different user model. A more generic way to create the user would be:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@myproject.com', 'password')" | python manage.py shell

ORIGINAL ANSWER

Here there is a simple version of the script to create a superuser:

echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'pass')" | python manage.py shell

Answer 2:

I was searching for an answer to this myself. I decided to create a Django command which extends the base createsuperuser command (GitHub):

from django.contrib.auth.management.commands import createsuperuser
from django.core.management import CommandError


class Command(createsuperuser.Command):
    help = 'Crate 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.',
        )

    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")

        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()

Example use:

./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'

This has the advantage of still supporting the default command use, while also allowing non-interactive use for specifying a password.

Answer 3:

I use ‘./manage.py shell -c’:

./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'adminpass')"

This doesn’t uses an extra echo, this has the benefit that you can pass it to a docker container for execution. Without the need to use sh -c “…” which gets you into quote escaping hell.

And remember that first comes username, than the email.

If you have a custom user model you need to import that and not auth.models.User

Answer 4:

I would suggest running a Data Migration, so when migrations are applied to the project, a superuser is created as part of the migrations. The username and password can be setup as environment variables. This is also useful when running an app in a container (see this thread as an example)

Your data migration would then look like this:

import os
from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ('<your_app>', '<previous_migration>'),
    ] # can also be emtpy if it's your first migration

    def generate_superuser(apps, schema_editor):
        from django.contrib.auth.models import User

        DJANGO_DB_NAME = os.environ.get('DJANGO_DB_NAME', "default")
        DJANGO_SU_NAME = os.environ.get('DJANGO_SU_NAME')
        DJANGO_SU_EMAIL = os.environ.get('DJANGO_SU_EMAIL')
        DJANGO_SU_PASSWORD = os.environ.get('DJANGO_SU_PASSWORD')

        superuser = User.objects.create_superuser(
            username=DJANGO_SU_NAME,
            email=DJANGO_SU_EMAIL,
            password=DJANGO_SU_PASSWORD)

        superuser.save()

    operations = [
        migrations.RunPython(generate_superuser),
    ]

Hope that helps!

Answer 5:

You could write a simple python script to handle the automation of superuser creation. The User model is just a normal Django model, so you’d follow the normal process of writing a stand-alone Django script. Ex:

import django
django.setup()

from django.contrib.auth.models import User

u = User(username='unique_fellow')
u.set_password('a_very_cryptic_password')
u.is_superuser = True
u.is_staff = True
u.save()

You can also pass createsuperuser a few options, namely --noinput and --username, which would let you automatically create new superusers, but they would not be able to login until you set a password for them.

Answer 6:

Current most voted answer:

  • Deletes the user if it exists and as noted by @Groady in the comments you risk unintentionally deleting any associated records via a cascade delete.
  • Checks superuser existence filtering by mail so if two superusers have the same mail god knows which one it deletes.
  • It is cumbersome to update the script parameters: username, password, and mail.
  • Does not log what it did.

An improved version would be:

USER="admin"
PASS="super_password"
MAIL="admin@mail.com"
script="
from django.contrib.auth.models import User;

username = '$USER';
password = '$PASS';
email = '$MAIL';

if User.objects.filter(username=username).count()==0:
    User.objects.create_superuser(username, email, password);
    print('Superuser created.');
else:
    print('Superuser creation skipped.');
"
printf "$script" | python manage.py shell

Answer 7:

As of Django 3.0 you can use default createsuperuser --noinput command and set all required field (including password) as environment variables DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAIL for example. --noinput flag is required.

This comes from the original docs: https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-createsuperuser

and i’ve just checked – it works. Now you can easily export those environment vars and add createsuperuser to your scripts and pipelines.

Answer 8:

I used Tk421 one liner but got an error message as: 1) I think I am using a later version of Django (1.10) Manager isn't available; 'auth.User' has been swapped for 'users.User' 2) the order of the parameters to create_superuser was wrong.

So I replaced it with:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(email='admin@example.com', is_superuser=True).delete(); User.objects.create_superuser('admin', 'admin@example.com', 'nimda')" | python manage.py shell

and what I as really pleased with is that it works on a heroku deployment as well:

heroku run echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(email='admin@example.com', is_superuser=True).delete(); User.objects.create_superuser('admin', 'admin@example.com', 'nimda')" | python manage.py shell

This will work nicely repeatedly. I am using it the beginning of a project so don’t worry about the terrible cascaded deletes that might occur later.

I have revisited after some trouble with running this inside local() from fabric. what seemed to be happening is that the pipe symbol mean that it was getting interpreted locally rather than on heroku. To sort this I wrapped in the command in quotes. Then had to used triple double quotes for the python strings inside the single quotes of the whole python command.

heroku run "echo 'from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(email="""admin@example.com""", is_superuser=True).delete(); User.objects.create_superuser("""admin""", """admin@example.com""", """nimda""")' | python manage.py shell"

Answer 9:

A solution based on Adam Charnock‘s approach above is available as a Python package by now. It takes three steps:

  1. Install: pip install django-createsuperuserwithpassword

  2. Activate: INSTALLED_APPS += ("django_createsuperuserwithpassword", )

  3. Apply:

    python manage.py createsuperuserwithpassword \
            --username admin \
            --password admin \
            --email admin@example.org \
            --preserve
    

That’s it.

Answer 10:

very easy, listen on post syncdb signal and read superuser credentials from a configuration file and apply it.

checkout django-bootup

https://github.com/un33k/django-bootup/blob/master/README

Answer 11:

This small python script could create a normal user or a superuser

#!/usr/bin/env python

import os
import sys
import argparse
import random
import string
import django


def main(arguments):

    parser = argparse.ArgumentParser()
    parser.add_argument('--username', dest='username', type=str)
    parser.add_argument('--email', dest='email', type=str)
    parser.add_argument('--settings', dest='settings', type=str)
    parser.add_argument('--project_dir', dest='project_dir', type=str)
    parser.add_argument('--password', dest='password', type=str, required=False)
    parser.add_argument('--superuser', dest='superuser', action='store_true', required=False)

    args = parser.parse_args()

    sys.path.append(args.project_dir)
    os.environ['DJANGO_SETTINGS_MODULE'] = args.settings
    from django.contrib.auth.models import User
    django.setup()

    username = args.username
    email = args.email
    password = ''.join(random.sample(string.letters, 20)) if args.password is None else args.password
    superuser = args.superuser 

    try:
        user_obj = User.objects.get(username=args.username)
        user_obj.set_password(password)
        user_obj.save()
    except User.DoesNotExist:
    if superuser:
            User.objects.create_superuser(username, email, password)
    else:
        User.objects.create_user(username, email, password)

    print password


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

–superuser & –password are not mandatory.

If –superuser is not defined, normal user will be created
If –password is not defined, a random password will be generated

    Ex : 
        /var/www/vhosts/PROJECT/python27/bin/python /usr/local/sbin/manage_dja_superusertest.py --username USERNAME --email TEST@domain.tld --project_dir /var/www/vhosts/PROJECT/PROJECT/ --settings PROJECT.settings.env 

Answer 12:

This is what I cobbled together for Heroku post_deploy and a predefined app.json variable:

if [[ -n "$CREATE_SUPER_USER" ]]; then
    echo "==> Creating super user"
    cd /app/example_project/src
    printf "from django.contrib.auth.models import User\nif not User.objects.exists(): User.objects.create_superuser(*'$CREATE_SUPER_USER'.split(':'))" | python /app/example_project/manage.py shell
fi

With this you can have a single env variable:

CREATE_SUPER_USER=admin:admin@example.com:password

I like the shell –command option, but not sure how the get newline character in the command script. Without the newline the if expression results in syntax error.

Answer 13:

Go to command prompt and type:

C:\WINDOWS\system32>pip install django-createsuperuser
Collecting django-createsuperuser
  Downloading https://files.pythonhosted.org/packages/93/8c/344c6367afa62b709adebee039d09229675f1ee34d424180fcee9ed857a5/django-createsuperuser-2019.4.13.tar.gz
Requirement already satisfied: Django>1.0 in c:\programdata\anaconda3\lib\site-packages (from django-createsuperuser) (2.2.1)
Requirement already satisfied: setuptools in c:\programdata\anaconda3\lib\site-packages (from django-createsuperuser) (41.0.1)
Requirement already satisfied: sqlparse in c:\programdata\anaconda3\lib\site-packages (from Django>1.0->django-createsuperuser) (0.3.0)
Requirement already satisfied: pytz in c:\programdata\anaconda3\lib\site-packages (from Django>1.0->django-createsuperuser) (2018.7)
Building wheels for collected packages: django-createsuperuser
  Running setup.py bdist_wheel for django-createsuperuser ... done
  Stored in directory: C:\Users\Arif Khan\AppData\Local\pip\Cache\wheels\0c\96\2a\e73e95bd420e844d3da1c9d3e496c92642a4f2181535440db2
Successfully built django-createsuperuser
Installing collected packages: django-createsuperuser

if not executed the migration then go to django application folder and execute following

  1. python manage.py migrate
  2. python manage.py createsuperuser

then bingo.

Answer 14:

python manage.py shell -c "from django.contrib.auth.models import User; \
                           User.objects.filter(username='admin1').exists() or \
                           User.objects.create_superuser('admin1',
                           'admin1@example.com', 'admin1')"

References