How to create a Django superuser if it doesn't exist non-interactively?
Asked Answered
O

3

19

I want to automate creation of Django users via a Bash script. I found this snippet which almost suits my needs:

echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" |\
    python manage.py shell

How can I modify it so that it's a nop if the user already exists?

Olney answered 28/9, 2016 at 10:16 Comment(0)
K
35

Using manage.py shell

You can use the QuerySet API methods to check if a user exists, and then create it if it doesn't. Also, it may be easier to put the code in a heredoc:

cat <<EOF | python manage.py shell
from django.contrib.auth import get_user_model

User = get_user_model()  # get the currently active user model,

User.objects.filter(username='admin').exists() or \
    User.objects.create_superuser('admin', '[email protected]', 'pass')
EOF

Using a custom management command

Another, more maintainable option is to add a custom management command for your Django app. Adapting the example from the docs, edit yourapp/management/commands/ensure_adminuser.py to look like this:

import os
from django.contrib.auth import get_user_model
from django.core.management.base import BaseCommand

class Command(BaseCommand):
    help = "Creates an admin user non-interactively if it doesn't exist"

    def add_arguments(self, parser):
        parser.add_argument('--username', help="Admin's username")
        parser.add_argument('--email', help="Admin's email")
        parser.add_argument('--password', help="Admin's password")
        parser.add_argument('--no-input', help="Read options from the environment",
                            action='store_true')

    def handle(self, *args, **options):
        User = get_user_model()

        if options['no_input']:
            options['username'] = os.environ['DJANGO_SUPERUSER_USERNAME']
            options['email'] = os.environ['DJANGO_SUPERUSER_EMAIL']
            options['password'] = os.environ['DJANGO_SUPERUSER_PASSWORD']

        if not User.objects.filter(username=options['username']).exists():
            User.objects.create_superuser(username=options['username'],
                                          email=options['email'],
                                          password=options['password'])

Then you can call the new custom command from your Bash script like this:

python manage.py ensure_adminuser --username=admin \
    [email protected] \
    --password=pass
Kissable answered 28/9, 2016 at 11:0 Comment(2)
this answer is complete, helped me a lot. Thx :)Inexorable
You should also be able to run this by setting the three environment variables DJANGO_* and then running the script without arguments. Better security.Coomer
S
3

This bash function does the trick, even if you have a custom user model in your app:

create-superuser () {
    local username="$1"
    local email="$2"
    local password="$3"
    cat <<EOF | python manage.py shell
from django.contrib.auth import get_user_model

User = get_user_model()

if not User.objects.filter(username="$username").exists():
    User.objects.create_superuser("$username", "$email", "$password")
else:
    print('User "{}" exists already, not created'.format("$username"))
EOF
}

Credits to Eugene Yarmash for the original idea.

Spongin answered 24/4, 2018 at 13:56 Comment(0)
E
1

you can use get_or_create(). If it exists it will do nothing, else it will create one.

You'd have to set the is_staff and is_superuser to True manually

Edentate answered 28/9, 2016 at 10:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.