【问题标题】:Automatically create an admin user when running Django's ./manage.py syncdb运行 Django 的 ./manage.py syncdb 时自动创建管理员用户
【发布时间】:2010-11-30 19:27:06
【问题描述】:

我的项目处于早期开发阶段。我经常删除数据库并运行manage.py syncdb 从头开始​​设置我的应用程序。

不幸的是,这总是弹出:

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): 

然后您提供了用户名、有效的电子邮件地址和密码。这很乏味。我已经厌倦了输入test\nx@x.com\ntest\ntest\n

如何在运行manage.py syncdb 时自动跳过此步骤并以编程方式创建用户?

【问题讨论】:

  • syncdb 已被弃用以支持数据迁移

标签: django automation django-syncdb


【解决方案1】:

我知道这个问题已经回答了但是......

一种更简单的方法是在创建超级用户后将身份验证模块数据转储到 json 文件中:

 ./manage.py dumpdata --indent=2 auth > initial_data.json

您还可以转储会话数据:

./manage.py dumpdata --indent=2 sessions

然后您可以将会话信息附加到身份验证模块转储中(并可能增加 expire_date 使其永远不会过期......永远;-)。

从那时起,您可以使用

/manage.py syncdb --noinput

在创建数据库时加载超级用户和他的会话,没有交互式提示询问您有关超级用户的信息。

【讨论】:

  • 这确实应该是公认的答案。最直接的国际海事组织。链接坏了。 :(
  • 我应该把initial_data.json放在哪里,以便syncdb找到它? The docs 说:“在每个已安装应用程序的fixtures 目录中”。是这样吗? ./eggs/Django-1.6.5-py2.7.egg/django/contrib/auth/fixtures ?
  • 自 Django 1.7 起已弃用:docs.djangoproject.com/en/1.7/howto/initial-data/… 现在您可以使用数据迁移。
【解决方案2】:

不要删除整个数据库,只需在运行 syncdb 之前删除应用程序的表

这将在一行中为您完成(每个应用程序):

python manage.py sqlclear appname | python manage.py dbshell

第一个命令将查看您的应用并生成删除表所需的 SQL。然后将此输出通过管道传输到 dbshel​​l 以执行它。

完成后,运行您的 syncdb 以重新创建表:

python manage.py syncdb

【讨论】:

  • 我喜欢这个答案。感谢您的建议!
  • 我也是,谢谢!干净的解决方案,已经使用它来进行干净的转储,我可以在需要时同步它。
【解决方案3】:

关键是在syncdb的时候使用--noinput然后用这个one liner创建超级用户

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

信用:http://source.mihelac.org/2009/10/23/django-avoiding-typing-password-for-superuser/

【讨论】:

  • 谢谢!这比其他的更清晰,更健壮和可扩展,非常适合在第一次运行代码、测试脚本和某些部署场景中使用,当然也适用于开发场景引出了这个问题。
【解决方案4】:

如果您希望能够像我一样真正从一个新数据库开始而不被问到超级用户问题,那么您可以取消注册提出该问题的信号处理程序。查看文件的最底部:

django/contrib/auth/management/__init__.py

查看如何执行超级用户功能的注册。我发现如果我将这段代码放在我的“models.py”中,我可以撤销这个注册,并且在“syncdb”期间永远不会被问到这个问题:

from django.db.models import signals
from django.contrib.auth.management import create_superuser
from django.contrib.auth import models as auth_app

# Prevent interactive question about wanting a superuser created.  (This
# code has to go in this otherwise empty "models" module so that it gets
# processed by the "syncdb" command during database creation.)

signals.post_syncdb.disconnect(
    create_superuser,
    sender=auth_app,
    dispatch_uid = "django.contrib.auth.management.create_superuser")

我不确定如何保证此代码在完成注册的 Django 代码之后运行。我曾认为这取决于您的应用程序或 django.contrib.auth 应用程序是否在 INSTALLED_APPS 中首先被提及,但无论我将它们放入的顺序如何,它似乎都对我有用。也许它们是按字母顺序完成的,我幸运的是我的应用程序的名称以晚于“d”的字母开头?或者 Django 是否足够聪明,可以先做自己的事情,然后我的,以防我想弄乱他们的设置?如果你发现了,请告诉我。 :-)

【讨论】:

  • 终于实现了这个并添加了一个钩子来自动创建我自己的测试用户(如果settings.DEBUGTrue)。再次感谢!
【解决方案5】:

我已经使用 south 克服了这个功能

它是任何 django 开发人员的必备品。

South 是一种工具,旨在帮助将更改迁移到实时站点,而不会破坏信息或数据库结构。生成的更改可以由 south 跟踪并使用生成的 python 文件 - 可以在备用数据库上执行相同的操作。

在开发过程中,我使用这个工具来 git 跟踪我的数据库更改 - 并对数据库进行更改而无需先销毁它。

  1. easy_install 南
  2. 将“南”添加到您安装的应用中

建议在应用程序上首次运行南。

$ python manage.py schemamigration appname --init

这将在该应用上启动架构检测。

$ python manage.py migrate appname

这将应用模型更改

  • 数据库将包含新模型。

第一次运行后更改模型

$ python manage.py schemamigration appname --auto

$ python manage.py migrate appname


模型将发生变化 - 数据不会被破坏。 再加上南方做得更多......

【讨论】:

    【解决方案6】:

    注意:自 1.7 版起,syncdb 命令为deprecated。使用migrateinstead

    Django 1.7 还引入了AppConfig 作为自定义应用程序初始化过程的手段。

    因此,从 Django 1.7 开始,实现您想要的最简单的方法是使用 AppConfig 的子类。

    假设您碰巧有自己的 example_app 添加到您的 INSTALLED_APPS 中,并且您想创建和 admin 用户使用 admin 密码从头开始运行./manage.py migrate。我还假设仅在 dev 环境中需要自动创建管理员用户 - 在 production 中不需要。

    将以下代码添加到example_app/apps.py

    # example_app/apps.py
    
    from django.apps import AppConfig
    from django.conf import settings
    from django.db.models.signals import post_migrate
    from django.contrib.auth.apps import AuthConfig
    
    
    USERNAME = "admin"
    PASSWORD = "admin"
    
    
    def create_test_user(sender, **kwargs):
        if not settings.DEBUG:
            return
        if not isinstance(sender, AuthConfig):
            return
        from django.contrib.auth.models import User
        manager = User.objects
        try:
            manager.get(username=USERNAME)
        except User.DoesNotExist:
            manager.create_superuser(USERNAME, 'x@x.com', PASSWORD)
    
    
    class ExampleAppConfig(AppConfig):
        name = __package__
    
        def ready(self):
            post_migrate.connect(create_test_user)
    

    另外在appsexample_app/__init__.py内的app配置中添加如下引用:

    # example_app/__init__.py
    
    default_app_config = 'example_app.apps.ExampleAppConfig'
    

    其中 default_app_config 是 AppConfig 子类的字符串 Python 路径,如提到的 here

    【讨论】:

    • 不幸的是,这不再适用于 Django 1.9,因为 django.contrib.auth 在配置时不再可用。这是设计使然,自 1.8 以来已被弃用,因此不太可能再次出现。这是非常可悲的......我喜欢这个黑客。
    • 好的,我想出了如何修复您的代码以使用 Django 1.9!我已经用修复编辑了你的答案。感谢您发布它:)
    【解决方案7】:

    manage.py reset 命令将重置您的数据库,而不会破坏您创建的超级用户。然而,数据确实需要重新导入。

    【讨论】:

    【解决方案8】:

    您可以使用 django-finalware 为您执行此操作。只需将finalware 添加到您的INSTALLED_APPS 并在您的settings.py 中包含以下内容:

    SITE_SUPERUSER_USERNAME = 'myadmin'
    SITE_SUPERUSER_EMAIL = 'myadmin@example.com'
    SITE_SUPERUSER_PASSWORD  = 'mypass'  # this can be set from a secret file.
    
    # optional object id. Ensures that the superuser id is not set to `1`.
    # you can use this as a simple security feature
    SITE_SUPERUSER_ID = '343'
    

    然后只需运行./manage.py syncdb (Django ./manage.py migrate (Django >= 1.7),它会自动为您创建超级用户或更新现有超级用户。

    不再提示您创建超级用户。

    【讨论】:

    • 如果它是您创建的,请添加免责声明
    • 兼容 Django >=2.0 吗?
    • @Dunatotatos 是的。 Django 版本支持也可以在 repo 的 .travis.yml 文件中找到
    【解决方案9】:

    从 Django 1.7 开始,建议的填充数据库的方法是通过数据迁移。要创建用于创建管理员的数据迁移,您应该首先创建一个空迁移:

    ./manage.py makemigrations --empty myapp --name create-superuser

    这将在myapp/migrations/000x__create-superuser.py 中创建一个空迁移。编辑文件使其看起来像这样:

    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    
    from django.db import migrations, models
    from django.contrib.auth.models import User
    
    
    def create_superuser(apps, schema_editor):
        User.objects.create_superuser(username='myadmin', password='mypassword', email='myemail@gmail.com')
    
    
    class Migration(migrations.Migration):
    
        dependencies = [('myapp', '000y_my-previous-migration-file'),]
    
        operations = [migrations.RunPython(create_superuser)]
    

    【讨论】:

      【解决方案10】:

      我已经解决了创建一个像这样的 python 脚本来重置我所有的东西[更新版本][1.8 也是]:

      import os
      import sys
      
      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "main.settings.dev")
      
      from django.conf import settings
      from django.core import management
      from django import get_version
      
      PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
      if PROJECT_ROOT not in sys.path:
          sys.path.append(PROJECT_ROOT)
      
      yn = raw_input('Are you sure you want to reset everything? (y/n) ')
      if yn == 'y':
      
          # Drops the db / creates the db
          if settings.DATABASES['default']['ENGINE'].find('mysql') != -1:
              os.system('mysqladmin -uroot -pIronlord0 -f drop db')
              os.system('mysqladmin -uroot -pIronlord0 -f create db')
          elif settings.DATABASES['default']['ENGINE'].find('psycopg2') != -1:
              os.system('psql -U postgres -c "DROP DATABASE db"')
              os.system('psql -U postgres -c "CREATE DATABASE db WITH OWNER = admin"')
          elif settings.DATABASES['default']['ENGINE'].find('sqlite3') != -1:
              try:
                  os.remove(os.path.join(PROJECT_ROOT, 'data.db'))
              except:
                  pass
      
          # Getting application handle here otherwise db gets allocated and it can not be destroyed.
          if get_version() > '1.6.10':
              from django.core.wsgi import get_wsgi_application
              application = get_wsgi_application()
      
          management.call_command('syncdb', interactive=False)
      
          # Creates admin/password
          from django.contrib.auth.management.commands import changepassword
          management.call_command('createsuperuser', interactive=False, username="admin", email="xxx@example.com")
          command = changepassword.Command()
          command._get_pass = lambda *args: 'password'
          if get_version() >= '1.8':
              command.execute(username="admin")
          else:
              command.execute("admin")
      
      
          # Creates the default site entry
          from django.contrib.sites.models import Site
          site = Site.objects.get_current()
          site.domain = 'www.example.com'
          site.name = ' xxx '
          site.save()
      

      它就像一个魅力!

      P.S.:在运行此脚本之前,请务必停止上述 db 负责的(测​​试)服务器!

      【讨论】:

        【解决方案11】:

        看看dumpdata管理命令。例如:

        python manage.py dumpdata > initial_data.json
        

        如果这个名为fixture 的文件被命名为initial_data(.xml 或.json),那么syncdb 命令将选择它并相应地填充您的表。它仍然会询问您是否要创建用户,但我相信您可以放心地回答“否”,之后它将根据您的夹具填充数据库。

        更多信息请访问docs

        【讨论】:

        • 如果您的 initial_data.json 中有超级用户和会话信息,您可以将 --noinput 选项附加到 syncdb 以缩短交互式提示
        【解决方案12】:

        使用 sqlite 进行开发。 通过删除文件清除数据库。 从灯具加载管理员。

        更改 manage.py (django 1.4):

        # hack to prevent admin promt
        if  len(sys.argv) == 2 and sys.argv[1] == 'syncdb':
            sys.argv.append('--noinput')
        

        【讨论】:

        • if 'syncdb' in sys.argv: sys.argv.append('--noinput')
        【解决方案13】:

        我对此的解决方案是在清除我的数据库时不删除该身份验证表。

        【讨论】:

          【解决方案14】:

          如果您更喜欢将初始化代码直接键入 python 源文件,修改后的代码 manage.py 可能会有所帮助(感谢 Cjkjvfnby 的小代码!):

          #!/usr/bin/env python
          import os
          import sys
          
          if __name__ == "__main__":
              # set your django setting module here
              os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings") 
          
              from django.core.management import execute_from_command_line
          
              # hack to prevent admin prompt
              if len(sys.argv) == 2 and sys.argv[1] == 'syncdb':
                  sys.argv.append('--noinput')
          
              execute_from_command_line(sys.argv)
          
              # additional process for creation additional user, misc data, and anything
              for arg in sys.argv:
                  # if syncdb occurs and users don't exist, create them
                  if arg.lower() == 'syncdb':
                      print 'syncdb post process...'
                      from django.contrib.auth.models import User
          
                      admin_id = 'admin'
                      admin_email = 'superuser@mail.com'
                      admin_password = 'superuser_password'
                      additional_users = [
                                          ['tempuser', 'user_email@mail.com', 'tempuser_password']
                                          ]
          
                      # admin exists?
                      user_list = User.objects.filter(username=admin_id)
                      if len(user_list) == 0: 
                          print 'create superuser: ' + admin_id
                          new_admin = User.objects.create_superuser(admin_id, admin_email, admin_password)
          
                      # additional user exists?
                      for additional_user in additional_users:
                          user_list = User.objects.filter(username=additional_user[0])
                          if len(user_list) == 0: 
                              print 'create additional user: ' + additional_user[0]
                              new_admin = User.objects.create_user(additional_user[0], additional_user[1], additional_user[2])
          
                      # any other data
          

          我只是在这里展示用户创建代码,但您可以根据需要进一步增强此代码。

          【讨论】:

            【解决方案15】:

            我使用 sqlite 作为开发数据库。更改模型类后,只需使用 sqlite manager(firefox 插件,打开以检查数据)删除相应的表,然后运行 ​​manage.py syncdb 以重新创建缺少的内容。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2013-06-06
              • 2013-02-17
              • 2011-01-20
              • 1970-01-01
              • 1970-01-01
              • 2019-06-30
              • 2015-04-25
              相关资源
              最近更新 更多