运行Django的./manage.py syncdb时自动创build一个admin用户

我的项目正在发展。 我经常删除数据库并运行manage.py syncdb从头开始设置我的应用程序。

不幸的是,这总是popup:

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

然后你提供了一个用户名,有效的电子邮件地址和密码。 这很乏味。 我厌倦了inputtest\nx@x.com\ntest\ntest\n

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

我知道这个问题已经被回答了,但…

更简单的方法是在创build超级用户后将auth模块数据转储到json文件中:

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

您也可以转储会话数据:

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

然后,您可以将会话信息附加到auth模块转储(并可能增加expire_date,以便它不会过期…-;)。

从那时起,你可以使用

 /manage.py syncdb --noinput 

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

运行syncdb之前,请删除您的应用程序的表格,而不是删除整个数据库

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

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

第一个命令将查看您的应用程序并生成所需的SQL来删除表。 这个输出然后被传送到dbshel​​l来执行它。

完成后,运行syncdb重新创build表:

 python manage.py syncdb 

关键是在syncdb时使用--noinput ,然后使用这个--noinput来创build超级用户

 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/

如果你希望这个能力 – 就像我一样 – 真正从一个全新的数据库开始,而不会被问到这个超级用户的问题,那么你可以取消注册这个问题的信号处理程序。 检查文件的最底部:

 django/contrib/auth/management/__init__.py 

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

 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刚刚足够聪明,首先做自己的东西,然后我的情况下,我想弄糟他们的设置? 让我知道,如果你发现。 🙂

我已经使用南方克服了这个function

它是任何Django开发者必须拥有的。

South是一个工具,旨在帮助将更改迁移到活动站点,而不会破坏信息或数据库结构。 南方可以跟踪生成的更改,并使用生成的python文件 – 可以在替代数据库上执行相同的操作。

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

  1. easy_install向南
  2. 添加“南”到您的安装的应用程序

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

$ python manage.py schemamigration appname --init

这将启动该应用程序的模式检测。

$ python manage.py migrate appname

这将应用模型更改

  • 数据库将有新的模型。

第一次运行后更改模型

$ python manage.py schemamigration appname --auto

$ python manage.py migrate appname


模型将会改变 – 数据不会被破坏。 加上南还有更多…

注意:由于版本1.7 syncdb命令已被弃用 。 改用migrate

另外Django 1.7引入了AppConfig作为定制应用程序初始化过程的手段。

因此,因为Django 1.7实现你想要的最简单的方法是使用一个AppConfig的子类。

比方说,你碰巧有自己的example_app添加到你的INSTALLED_APPS并且你想用admin密码创build和pipe理用户,每当你运行./manage.py migrate从头开始./manage.py migrate 。 我还假设只有在开发环境中才需要创build自动pipe理用户,而不是在生产环境中。

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

 # example_app/config.py from django.apps import AppConfig from django.conf import settings from django.contrib.auth.management.commands import createsuperuser from django.db.models import signals from django.contrib.auth.models import User USERNAME = "admin" PASSWORD = "admin" class ExampleAppConfig(AppConfig): name = __package__ def ready(self): if not settings.DEBUG: return from django.contrib.auth import models as auth_models def create_testuser(**kwargs): User = auth_models.User manager = User.objects try: manager.get(username=USERNAME) except User.DoesNotExist: manager.create_superuser(USERNAME, 'x@x.com', PASSWORD) # Prevent interactive question about wanting a superuser created signals.post_migrate.disconnect(createsuperuser, sender=auth_models, dispatch_uid='django.contrib.auth.management.create_superuser') signals.post_migrate.connect(create_testuser, sender=auth_models, dispatch_uid='common.models.create_testuser') 

还要将以下引用添加到apps example_app/__init__.py的应用程序configuration中:

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

其中default_app_config是这里提到的AppConfig子类的stringPythonpath。

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

你可以使用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 <1.7)或./manage.py migrate (Django> = 1.7),它会自动为你创build一个超级用户或更新现有的超级用户。

你永远不会被提示创build一个超级用户了。

由于Django 1.7build议填充数据库的方式是通过数据迁移。 要创build用于创buildpipe理员的数据迁移,您应该先创build一个空迁移:

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

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

 # -*- 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)] 

我已经解决了创build一个这样的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() 

它就像一个魅力!

PS:在运行这个脚本之前,一定要停止你的(testing)服务器上面的数据库负责!

看看dumpdatapipe理命令。 例如:

 python manage.py dumpdata > initial_data.json 

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

更多信息可以在文档中find。

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

更改manage.py(django 1.4):

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

我的解决scheme是在删除数据库时不删除那个授权表。

如果你想直接input初始化代码到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 

我只是在这里显示用户创build代码,但是你可以更多地增加这个代码。

我正在使用sqlite作为开发数据库。 在更改模型类之后,只需使用sqlitepipe理器 (一个Firefox插件,打开检查数据),然后运行manage.py syncdb删除相应的表以重新创build缺less的内容。