在运行Django的./manage.py syncdb时自动创建一个管理员用户


82

我的项目处于早期开发中。我经常删除数据库,然后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为支持数据迁移已弃用
Sdra

Answers:


80

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

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

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

您还可以转储会话数据:

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

然后,您可以将会话信息附加到auth模块转储中(并可能增加expire_date,这样它就不会过期...永远;-)。

从那时起,您可以使用

/manage.py syncdb --noinput

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


1
这确实应该是公认的答案。最直接的IMO。链接断开。:(
bnjmn

4
我应该放在哪里initial_data.json以便syncdb找到它?文档说:“在每个已安装应用程序的Fixtures目录中”。那是例如./eggs/Django-1.6.5-py2.7.egg/django/contrib/auth/fixtures吗?
user272735 2014年

2
自Django 1.7起已弃用该文件:docs.djangoproject.com/en/1.7/howto/initial-data / ...现在,您可以使用数据迁移了。
Germain Chazot 2015年

49

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

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

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

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

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

python manage.py syncdb

2
我喜欢这个答案。谢谢你的建议!
2010年

我也是,谢谢!干净的解决方案,已经使用它进行了干净的转储,我可以在需要时进行同步。
Andrei-Niculae Petre

28

关键是要--noinput在syncdb时使用,然后使用它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/


5
谢谢!这比其他方法更清晰,更健壮和可扩展,非常适合第一次运行代码时使用,以及在测试脚本和某些部署方案中使用,当然,在导致问题的开发方案中也是如此。
nealmcb 2014年

16

如果您希望像我一样有能力在不询问超级用户问题的情况下真正从一个新的数据库开始,那么您只需注销注册询问该问题的信号处理程序即可。检出文件的最底部:

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)。再次感谢!
的付费书呆子

11

我已经克服了南方使用此功能

对于任何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


模型将已更改-数据不会被破坏。再加上南方还有更多...


9

注意:自1.7版syncdb命令已弃用。使用migrate 代替

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

因此,自Django 1.7起,实现所需目标的最简单方法是采用AppConfig的子类。

假设您碰巧将自己example_app的添加到您的计算机中,INSTALLED_APPS并且无论何时从头开始运行,您都希望使用管理员密码创建和管理用户。我还假设仅在开发环境中才需要自动创建管理员用户,而在生产环境中则不需要。./manage.py migrate

将以下代码添加到 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)

还要在apps内部添加以下对app配置的引用example_app/__init__.py

# example_app/__init__.py

default_app_config = 'example_app.apps.ExampleAppConfig'

凡default_app_config是一个字符串的Python路径AppConfig子提到这里


2
不幸的是,由于Django 1.9django.contrib.auth在配置时不再可用,因此该功能自Django 1.9起不再可用。这是设计使然,从1.8开始不推荐使用,因此不太可能再出现。太可悲了...我喜欢这个hack。
阿德里安·彼得雷斯库

好的,我弄清楚了如何修复您的代码以使其与Django 1.9兼容!我已使用修复程序对您的答案进行了编辑。感谢您发布:)
Adrian Petrescu,2013年


3

您可以使用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),它将自动创建一个超级用户或为您更新现有的超级用户。

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


如果它是由您创建的,则请添加免责声明
Erion S

它与Django> = 2.0兼容吗?
Dunatotatos

@Dunatotatos是的。Django版本支持也可以在仓库的.travis.yml文件中找到
un33k,

3

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

3

我已经解决了创建一个像这样的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:在运行此脚本之前,请确保停止负责上述db的(测试)服务器!


2

看一下dumpdata管理命令。例如:

python manage.py dumpdata > initial_data.json

如果此文件名为fixture,名为initial_data(.xml或.json),则syncdb命令将对其进行拾取并相应地填充表。它仍然会询问您是否要创建用户,但是我相信您可以安全地回答“否”,此后它将根据您的夹具来填充数据库。

有关更多信息,请参见docs


1
如果您在initial_data.json中具有超级用户和会话信息,则可以将--noinput选项附加到syncdb上,以缩短交互式提示的速度
philgo20'3:

2

用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')

2
if 'syncdb' in sys.argv: sys.argv.append('--noinput')
2013年

1

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


1

如果您希望直接将初始化代码键入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

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


0

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

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.