Автоматически создавать пользователя-администратора при запуске 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 02

Ответы:

80

Я знаю, что на этот вопрос уже дан ответ, но ...

Гораздо более простой подход - сбросить данные модуля аутентификации в файл json после создания суперпользователя:

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

Вы также можете сбросить данные сеансов:

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

Затем вы можете добавить информацию о сеансе в дамп модуля аутентификации (и, возможно, увеличить expire_date, чтобы он не истекал ... никогда ;-).

С этого момента вы можете использовать

/manage.py syncdb --noinput

для загрузки суперпользователя и его сеанса при создании базы данных без интерактивного запроса о суперпользователе.

philgo20
источник
1
Это действительно должен быть принятый ответ. Самый простой ИМО. Ссылка не работает. :(
bnjmn
4
Куда мне поставить, initial_data.jsonчтобы тот syncdbнашел? В документации говорится: «В каталоге fixtures каждого установленного приложения» . Это например ./eggs/Django-1.6.5-py2.7.egg/django/contrib/auth/fixtures?
user272735 07
2
Это устарело с Django 1.7: docs.djangoproject.com/en/1.7/howto/initial-data/… Теперь вы можете использовать перенос данных.
Germain Chazot
49

Вместо того, чтобы удалять всю базу данных, просто удалите таблицы своего приложения перед запуском syncdb

Это выполнит это за вас одной строкой (для каждого приложения):

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

Первая команда просмотрит ваше приложение и сгенерирует требуемый SQL для удаления таблиц. Затем этот вывод передается в dbshell для его выполнения.

После этого запустите ваш syncdb, чтобы воссоздать таблицы:

python manage.py syncdb
Андре Миллер
источник
2
Мне нравится этот ответ. Спасибо за предложение!
ropable
я тоже, спасибо! чистое решение, уже использующее его для получения чистого дампа, который я синхронизирую всякий раз, когда мне нужно.
Андрей-Никулае Петре
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
16

Если вы хотите, чтобы у вас была возможность - как и я - действительно начать со свежей базой данных, не задавая этот вопрос суперпользователя, вы можете просто отменить регистрацию обработчика сигналов, который задает этот вопрос. Загляните в самый низ файла:

django/contrib/auth/management/__init__.py

чтобы увидеть, как выполняется регистрация функции суперпользователя. Я обнаружил, что могу отменить эту регистрацию и никогда не получить вопрос во время "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 достаточно умен, чтобы сначала делать свои вещи, а потом мои на случай, если я захочу испортить их настройки? Дай мне знать, если узнаешь. :-)

Брэндон Роудс
источник
Наконец, реализовал это и добавил ловушку для автоматического создания собственного тестового пользователя (если settings.DEBUGесть True). Еще раз спасибо!
оплачиваемый ботаник
11

Я преодолел эту особенность, используя юг

Это должно быть у любого разработчика django.

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)

Также добавьте следующую ссылку на конфигурацию приложения внутри приложений example_app/__init__.py:

# example_app/__init__.py

default_app_config = 'example_app.apps.ExampleAppConfig'

Где default_app_config - это строковый путь Python к AppConfigподклассу, как упоминалось здесь .

Арчибальд
источник
2
К сожалению, это больше не работает с Django 1.9, потому что django.contrib.authбольше не доступно во время настройки. Это сделано намеренно и не рекомендуется с версии 1.8, поэтому вряд ли когда-нибудь вернется. Что очень печально ... Мне понравился этот хак.
Адриан Петреску,
Хорошо, я понял, как исправить ваш код для работы с Django 1.9! Я отредактировал ваш ответ исправлениями. Спасибо, что разместили :)
Адриан Петреску
5

Команда manage.py resetсбросит вашу базу данных, не уничтожая созданного вами суперпользователя. Однако данные необходимо повторно импортировать.

tjb
источник
1
сброс был заменен сбросом с помощью Django 1.5 stackoverflow.com/questions/15454008/…
tjb
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), и он автоматически создаст суперпользователя или обновит существующий за вас.

Вам больше не будет предлагаться создать суперпользователя.

un33k
источник
Если он был создан вами, пожалуйста, добавьте отказ от ответственности
Erion S
Совместимо ли оно с Django> = 2.0?
Дунатотатос
@Dunatotatos да, это так. Поддержка версии Django также можно найти в файле
репозитория .travis.yml
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!

Filippo.IOVINE
источник
2

Взгляните на команду dumpdataуправления. Например:

python manage.py dumpdata > initial_data.json

Если этот файл, называемый initial_dataфикстурой , имеет имя (.xml или .json), то syncdbкоманда выберет его и соответствующим образом заполнит ваши таблицы. Он по-прежнему будет спрашивать вас, хотите ли вы создать пользователя, но я считаю, что вы можете спокойно ответить «нет», после чего он заполнит базу данных на основе вашего устройства.

Более подробную информацию об этом можно найти в документации .

Райан Даффилд
источник
1
Вы можете добавить параметр --noinput в syncdb для быстрого доступа к интерактивной подсказке, если у вас есть информация о суперпользователе и сеансе в вашем initial_data.json
philgo20
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')
Cjkjvfnby
источник
2
if 'syncdb' in sys.argv: sys.argv.append('--noinput')
TimP
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

Я просто показываю здесь код создания пользователя, но вы можете улучшить этот код по своему усмотрению.

Kenial
источник
0

Я использую sqlite как базу данных для разработчиков. После изменения классов модели просто удалите соответствующие таблицы с помощью диспетчера sqlite (плагин firefox, который в любом случае открыт для проверки данных) и запустите, manage.py syncdbчтобы воссоздать то, что отсутствует.

Янченко
источник