Django provides us Admin Panel for it's users. So we need not worry about creating a separate Admin page or providing authentication feature as Django provides us that feature. Before using this feature, you must have migrated your project, otherwise the superuser database will not be created.
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', '[email protected]', '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', '[email protected]', 'pass')" | python manage.py shell
As of Django 3.0 you can use default createsuperuser --noinput
command and set all required fields (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
It is the most convenient way to add createsuperuser
to scripts and pipelines.
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 '[email protected]'
This has the advantage of still supporting the default command use, while also allowing non-interactive use for specifying a password.
I use './manage.py shell -c':
./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', '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, then the email.
If you have a custom user model you need to import that and not auth.models.User
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_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!
EDIT:
Some might raise the question how to set these environment variables and make Django aware of them. There are a lot of ways and it's been answered in other SO posts, but just as a quick pointer, creating a .env
file is a good idea. You could then use the python-dotenv package, but if you have setup a virtual environment with pipenv, it will automatically set the envvars in your .env
file. Likewise, running your app via docker-compose can read in your .env
file.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With