【问题标题】:How to automate createsuperuser on django?如何在 django 上自动创建超级用户?
【发布时间】:2018-04-01 11:44:17
【问题描述】:

我想在django 上自动运行manage.py createsuperuser,但似乎无法设置默认密码。

我怎样才能得到这个?它必须独立于 django 数据库。

【问题讨论】:

  • 您是否考虑过将您创建的超级用户保存为一个夹具并使用 manage.py 加载它?
  • @turbotux Hendrik F answer 采用与您建议的方法类似的方法,增加了从环境变量(或文件系统...)读取值(登录名、密码...)的能力。我强烈建议您朝这个方向发展,而不是使用临时 python 脚本,后者在您重新启动应用程序时会出现问题。

标签: django


【解决方案1】:

如果您直接引用 User,您的代码将无法在 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

【讨论】:

  • 在尝试在 heroku 中创建超级用户并且您的网络阻塞端口 5000 时非常有用
  • 我会删除现有的超级用户,所以这对每个构建都有效: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
  • 就我个人而言,我认为在每个构建中删除用户并不是一个好主意。您可能会通过级联删除无意中删除任何相关记录。如果用户已经存在(或更新现有用户记录),则更安全的选择是简单地退出。
  • 至少在 Django 1.11 上。参数的顺序是 ('username', 'email', 'pass'),而不是 ('email', 'username', 'pass')。见:docs.djangoproject.com/en/1.11/ref/contrib/auth/…
  • 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')
【解决方案2】:

从 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添加到脚本和管道中是最方便的方法。

【讨论】:

  • 谢谢!这非常有帮助,非常适合与docker-compose 一起使用这个答案应该在顶部
  • 这对于 docker 设置非常重要。非常感谢。
  • 在 Dockerizing Django 的上下文中,这太棒了!正是我想知道的是否存在。
  • 如何在 docker compose 中使用它?
  • @PhilO 使用提到的环境变量创建新的“.env”文件。您可以使用容器内的 --env-file docs.docker.com/compose/environment-variables 将变量附加到您的 django 容器中运行“python manage.py createsuperuser --no-input”
【解决方案3】:

我自己也在寻找这个问题的答案。我决定创建一个扩展基本 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'

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

【讨论】:

  • 我希望默认的 createsuperuser 也有这个 --password 字段
  • 您可以添加一个示例用法:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'
  • createsuperuser2如何映射到这个类、函数
  • @SrinathGanesh 看看docs.djangoproject.com/en/1.8/howto/custom-management-commands 您需要将python 文件命名为createsuperuser2.py 并将其放入上面链接中定义的目录结构中。
  • 通过命令行传递密码是不安全的。另一个用户可以在进程列表中看到密码。
【解决方案4】:

我使用'./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

【讨论】:

  • 似乎对我不起作用,我看到了:AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
  • 当你有一个像 users.User 这样的自定义用户模型时,你需要从中导入,而不是从 auth.User 导入
【解决方案5】:

我建议运行Data Migration,因此当迁移应用到项目时,会创建一个超级用户作为迁移的一部分。用户名和密码可以设置为环境变量。这在容器中运行应用程序时也很有用(以 this thread 为例)

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

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

希望有帮助!

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

【讨论】:

  • 提示:请考虑这种方法。这是一个高质量的答案:它自然地利用 Django 的内置功能来回答问题,而不是回显临时 python 脚本,而且它自然地解决了已接受答案的最大问题(迁移仅在部署中应用一次,所以用户只被创建一次)。它在容器环境中运行良好。
  • 这似乎是一个很好的答案。我还是不知道这段代码在项目中的哪个位置合适?
  • 它应该在您的迁移文件夹中,例如 root/⁨mysite⁩/myapp⁩/⁨migrations⁩ - 如果您阅读文档,它会解释如何创建一个空迁移并修改 python manage.py makemigrations --empty yourappname
  • 为什么需要 DJANGO_DB_NAME?它从未使用过。
  • 您应该提到添加以下内容以将 .env 变量加载到 settings.py 文件:python # loading .env from dotenv import load_dotenv from pathlib import Path env_path = Path('.', '.env') load_dotenv(dotenv_path=env_path)
【解决方案6】:

您可以编写一个简单的 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,它们可以让您自动创建新的超级用户,但在您为其设置密码之前,他们将无法登录。

【讨论】:

  • cretesuperuser 可以,但是那怎么设置密码呢?我想在 bash 脚本中执行此操作...
【解决方案7】:
DJANGO_SUPERUSER_USERNAME=testuser \
DJANGO_SUPERUSER_PASSWORD=testpass \
python manage.py createsuperuser --noinput

Documentation for the createuser command

【讨论】:

  • 这是最简单的解决方案。但是你可以用其他参数覆盖noinput 标志:DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email admin@email.com --noinput
  • 此方法在 Django 3.0 中有效,后来在 Django 2.2 中无效
  • 在 Django 4.0 上不需要传递电子邮件。否则会收到如下错误:CommandError: You must use --email with --noinput.
【解决方案8】:

当前投票最多的答案:

  • 如果用户存在,则删除该用户,并且正如 @Groady 在 cmets 中所指出的那样,您可能会通过级联删除无意中删除任何相关记录。
  • 通过邮件检查超级用户是否存在过滤,因此如果两个超级用户拥有相同的邮件,天知道它会删除哪一个。
  • 脚本参数更新比较麻烦:用户名、密码、邮箱。
  • 不记录它所做的事情。

改进的版本是:

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

【讨论】:

  • 比公认的答案更干净(更好)。您也可以使用:if not User.objects.filter(username = username).exists(),
【解决方案9】:

基于Adam Charnock 的方法abovesolution 现在可以作为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
    

就是这样。

【讨论】:

    【解决方案10】:

    我喜欢使用 serverless/docker 构建 AppConfig.ready 方法/事件来执行这种操作,这里是一个例子:

    import logging
    
    from django.apps import AppConfig
    from django.contrib.auth import get_user_model
    from django.utils.translation import gettext_lazy as gettext
    
    
    class Config(AppConfig):
        name: str = "apps.policy"
        label: str = "policy"
        verbose_name: str = gettext("Policies")
    
        @classmethod
        def ready(cls):
            user_model = get_user_model()
            log = logging.getLogger(cls.label)
    
            try:
                if not user_model.objects.filter(username="admin").first():
                    log.info("Creating default superuser with user and password: admin")
                    user_model.objects.create_superuser('admin', 'admin@admin.admin', 'admin')
            except Exception:
                log.warn(
                    "Found an error trying to create the superuser, if you aren't"
                    "run the user model migration yet, ignore this message"
                )
    
    

    当我第一次在数据库中启动我的项目时,我看到:

    2021-06-22 06:19:02 policy/info  Creating default superuser with user and password: admin
    Performing system checks...
    
    System check identified no issues (1 silenced).
    June 22, 2021 - 06:19:02
    Django version 3.1.12, using settings 'settings.env.default'
    Starting development server at http://0.0.0.0:8027/
    Quit the server with CONTROL-C.
    

    【讨论】:

      【解决方案11】:

      使用 shell_plus 实际上要容易得多

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

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

      【讨论】:

        【解决方案12】:
        from django.core.management.base import BaseCommand, CommandError
        from django.contrib.auth.models import User
        
        class Command(BaseCommand):
        
            def handle(self, *args, **options):
        
                # The magic line
                User.objects.create_user(username= 'rmx',
                                        email='superuser@super.com',
                                        password='rmx55',
                                        is_staff=True,
                                        is_active=True,
                                        is_superuser=True
                )
        

        【讨论】:

          【解决方案13】:

          我这样解决了这个问题。

          wsgi.py 文件总是在 django 项目启动时运行。所以如果它不存在,我在这里运行创建超级用户命令。

          import os
          
          from django.contrib.auth.models import User
          from django.core.wsgi import get_wsgi_application
          
          os.environ.setdefault('DJANGO_SETTINGS_MODULE', {settings_file})
          
          application = get_wsgi_application()
          
          users = User.objects.all()
          if not users:
              User.objects.create_superuser(username="username", email="user@example.com", password="password", is_active=True, is_staff=True)
          

          这里可以添加一个函数。例如;如果此“user1”不存在,请添加“user1”。

          【讨论】:

            【解决方案14】:

            我使用 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"
            

            【讨论】:

              【解决方案15】:
              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')"
              

              【讨论】:

                【解决方案16】:

                这个小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 
                

                【讨论】:

                  【解决方案17】:

                  这是我为 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
                  

                  有了这个你可以有一个单一的环境变量:

                  CREATE_SUPER_USER=admin:admin@example.com:password
                  

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

                  【讨论】:

                    【解决方案18】:

                    您可以像这样在自定义命令中创建超级用户:

                    import os
                    
                    from django.contrib.auth.models import User
                    from django.core.management import BaseCommand, call_command
                    
                    from immo_project import settings
                    
                    
                    class Command(BaseCommand):
                        def handle(self, *args, **options):
                            call_command('createsuperuser', interactive=False, username='admin', email='test@example.com')
                            user = User.objects.get(username='admin')
                            user.set_password('password')
                            user.save()
                    

                    【讨论】:

                      【解决方案19】:

                      python manage.py shell &lt; mysite/create_superuser.py

                      mysite/create_superuser.py

                      from decouple import config
                      from django.db import IntegrityError
                      
                      # getting name,email & password from env variables
                      DJANGO_SU_NAME = config('DJANGO_SU_NAME')
                      DJANGO_SU_EMAIL = config('DJANGO_SU_EMAIL')
                      DJANGO_SU_PASSWORD = config('DJANGO_SU_PASSWORD')
                      
                      try:
                          superuser = User.objects.create_superuser(
                              username=DJANGO_SU_NAME,
                              email=DJANGO_SU_EMAIL,
                              password=DJANGO_SU_PASSWORD)
                          superuser.save()
                      except IntegrityError:
                          print(f"Super User with username {DJANGO_SU_NAME} is already present")
                      except Exception as e:
                          print(e)
                      

                      【讨论】:

                        【解决方案20】:

                        非常简单,监听 post syncdb 信号并从配置文件中读取超级用户凭据并应用它。

                        查看django-finalware 及其前身django-bootup [已弃用]

                        【讨论】:

                        【解决方案21】:

                        转到命令提示符并键入:

                        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

                        然后宾果游戏。

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2021-10-13
                          • 1970-01-01
                          • 1970-01-01
                          • 2015-05-11
                          • 2016-10-03
                          • 2016-10-27
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多