如何在Django上自动化createsuperuser?


128

我想自动运行manage.py createsuperuserdjango但是它似乎无法设置默认密码。

我怎么能得到这个?它必须独立于Django数据库。


1
您是否考虑过仅将创建的超级用户保存为夹具并使用manage.py加载它?
turbotux

1
@turbotux Hendrik F答案采用与您建议的类似的方法,具有从env vars(或文件系统,...)读取值(登录名,密码...)的功能。我强烈建议您朝这个方向发展,而不要使用即席python脚本,因为重新启动应用程序时会出现问题。
广告N

Answers:


145

如果直接引用用户,则您的代码将无法在AUTH_USER_MODEL设置更改为其他用户模型的项目中使用。创建用户的更通用的方法是:

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

原始答案

这里是创建超级用户的脚本的简单版本:

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

2
尝试在heroku中创建超级用户时超级有用,并且您的网络阻塞了端口5000
Vic

4
我将删除现有的超级用户,因此这对每个构建都有效:echo "from django.contrib.auth.models import User; User.objects.filter(email='admin@example.com').delete(); User.objects.create_superuser('admin@example.com', 'admin', 'nimda')" | python manage.py shell
Montaro

12
我个人认为删除每个版本上的用户不是一个好主意。您可能会冒风险通过级联删除无意中删除任何关联的记录。一个更安全的选择是,如果用户已经存在,则简单地进行纾困(或更新现有的用户记录)。
威尔

6
至少在Django 1.11上。参数的顺序是('username','email','pass'),而不是('email','username','pass')。参见:docs.djangoproject.com/en/1.11/ref/contrib/auth/…–
np8

3
from django.contrib.auth.models import User不再有效。使用这个: from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@myproject.com', 'my secure password')
dcalde

49

我本人正在寻找答案。我决定创建一个扩展基本createsuperuser命令(GitHub)的Django命令:

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

使用示例:

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

这样的优点是仍支持默认命令使用,同时还允许非交互式使用以指定密码。


4
这应该是最受欢迎的(也是公认的)答案。
bruno desthuilliers

我希望默认值createsuperuser也具有该--password字段
shadi

1
您可以添加示例用法:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'
shadi

2
如何createsuperuser2映射到此类,函数
Srinath Ganesh

2
@SrinathGanesh看一下docs.djangoproject.com/en/1.8/howto/custom-management-commands 您需要命名python文件,createsuperuser2.py并通过上面的链接将其放入定义的目录结构中。
ElectRocnic

43

我使用'./manage.py shell -c':

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

这不使用额外的回显,它的好处是您可以将其传递给docker容器执行。无需使用sh -c“ ...”,您就可以避免引号转入地狱。

记住,首先是用户名,而不是电子邮件。

如果您有自定义用户模型,则无需导入 auth.models.User


1
为我工作。谢谢!
TimH-Codidact

我似乎对我没有用:AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
Brodan

当您有一个自定义用户模型时,users.User 您需要从中导入而不是从中导入auth.User
yvess

30

我建议运行一个Data Migration,这样在将迁移应用于项目时,将创建一个超级用户作为迁移的一部分。可以将用户名和密码设置为环境变量。在容器中运行应用程序时,这也很有用(请参见此线程作为示例)

然后,您的数据迁移将如下所示:

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),
    ]

希望有帮助!

编辑:有些人可能会提出一个问题,即如何设置这些环境变量并使Django了解它们。有很多方法,在其他SO帖子中已经对此进行了回答,但是就像快速指针一样,创建.env文件也是一个好主意。然后,您可以使用python-dotenv软件包,但是如果您使用pipenv设置了虚拟环境,它将自动在.env文件中设置envvars 。同样,通过docker-compose运行您的应用程序可以读取.env文件。


1
提示:请考虑这种方法。这是一个高质量的答案:它自然利用Django的内置功能来回答问题,而不是回显即席python脚本,此外,它自然也解决了公认答案的最大问题(迁移仅在部署中应用一次,因此用户只能创建一次)。它在容器上下文中可以很好地工作。
广告N

这似乎是一个很好的答案。我仍然不知道这段代码在项目中适合什么位置?
Pablo Ruiz Ruiz

它应该位于您的migrations文件夹中,例如root/⁨mysite⁩/myapp⁩/⁨migrations⁩-如果您阅读了文档,它说明了如何创建一个空迁移并进行修改python manage.py makemigrations --empty yourappname
Hendrik F

为什么需要DJANGO_DB_NAME?它从未使用过。
thoroc

您应该提到添加以下内容以将.env var加载到settings.py文件中:python # loading .env from dotenv import load_dotenv from pathlib import Path env_path = Path('.', '.env') load_dotenv(dotenv_path=env_path)
thoroc

23

由于Django的3.0,你可以使用默认的createsuperuser --noinput命令,并设置所有必需的字段(包括密码)作为环境变量DJANGO_SUPERUSER_PASSWORDDJANGO_SUPERUSER_USERNAMEDJANGO_SUPERUSER_EMAIL例如。--noinput标志是必需的。

这来自原始文档:https : //docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-createsuperuser

而且我刚刚检查了-它有效。现在,您可以轻松导出这些环境变量,并将其添加createsuperuser到脚本和管道中。


14

您可以编写一个简单的python脚本来处理超级用户创建的自动化。该User模型只是普通的Django模型,因此您将遵循编写独立Django脚本的正常过程。例如:

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

您还可以传递createsuperuser几个选项,即--noinput--username,这将允许您自动创建新的超级用户,但是只有在为超级用户设置密码后,他们才能登录。


2
好的cretesuperuser,但是如何设置密码呢?我想在bash脚本中执行此操作...
caneta 2013年

10

当前投票最多的答案:

  • 删除用户(如果存在),并且如@Groady在注释中指出的那样,您可能会冒风险通过级联删除无意中删除任何关联记录。
  • 通过邮件检查超级用户是否存在过滤,以便两个超级用户拥有相同的邮件,上帝知道它删除了哪个。
  • 更新脚本参数很麻烦:用户名,密码和邮件。
  • 不记录所做的事情。

改进的版本将是:

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

2
比接受的答案干净(更好)。您可能还使用过:if not User.objects.filter(username = username).exists()
Philippe Fanaro,

5
DJANGO_SUPERUSER_USERNAME=testuser \
DJANGO_SUPERUSER_PASSWORD=testpass \
python manage.py createsuperuser --noinput

createuser命令的文档


这是最简单的解决方案。但是您可以noinput用其他参数覆盖flag:DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email admin@email.com --noinput
dannydedog

1

我使用Tk421一个内衬,但收到一条错误消息:1)我认为我正在使用Django(1.10)的更高版本Manager isn't available; 'auth.User' has been swapped for 'users.User'2)create_superuser的参数顺序错误。

因此,我将其替换为:

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

我真正感到高兴的是,它也可以在heroku部署中使用:

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

这将反复很好地工作。我在项目的开始就使用它,所以不必担心以后可能发生的可怕的级联删除。

在从fabric运行在local()内部遇到一些麻烦之后,我再次进行了回顾。似乎正在发生的事情是,管道符号意味着它是在本地而不是在heroku上解释的。为了对此进行排序,我将命令用引号引起来。然后必须在整个python命令的单引号内对python字符串使用三重双引号。

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"

1

溶液基于亚当诺克的做法以上可作为Python包现在。这需要三个步骤:

  1. 安装: pip install django-createsuperuserwithpassword

  2. 启用: INSTALLED_APPS += ("django_createsuperuserwithpassword", )

  3. 应用:

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

而已。



0

这个小的python脚本可以创建普通用户或超级用户

#!/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不是必需的。

如果未定义--superuser,将创建普通用户。如果未定义--password,将生成随机密码。

    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 

0

这是我为Heroku post_deploy和预定义的app.json变量拼凑而成的:

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

有了这个,您可以有一个env变量:

CREATE_SUPER_USER=admin:admin@example.com:password

我喜欢shell --command选项,但是不确定命令脚本中如何获取换行符。没有换行符,该if表达式将导致语法错误。


0

转到命令提示符并键入:

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

如果未执行迁移,则转到django应用程序文件夹并执行以下命令

  1. python manage.py迁移
  2. python manage.py createsuperuser

然后宾果游戏。


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

0

使用shell_plus实际上实际上要容易得多

echo "User.objects.create_superuser('test@test.com', 'test')" | python manage.py shell_plus

就像其他人提到的那样,使用Django 3.0,您可以通过环境变量传递凭据。但是,这种方法更加灵活,因为它允许您执行任何其他更复杂的任务,例如删除所有测试用户等。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.