Автоматически создавать пользователя с правами администратора при запуске Django's ./manage.py syncdb
Мой проект находится на ранней стадии разработки. Я часто удаляю базу данных и запускаю 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
?
15 ответов
Я знаю, что на вопрос уже дан ответ, но...
Гораздо более простой подход - выгрузить данные модуля auth в файл json после создания суперпользователя:
./manage.py dumpdata --indent=2 auth > initial_data.json
Вы также можете сбросить данные сессий:
./manage.py dumpdata --indent=2 sessions
Затем вы можете добавить информацию о сеансе в дамп модуля auth (и, возможно, увеличить expire_date, чтобы он не истек... никогда;-).
С этого момента вы можете использовать
/manage.py syncdb --noinput
загрузить суперпользователя и его сеанс при создании БД без интерактивного приглашения, спрашивающего вас о суперпользователе.
Вместо того чтобы удалять всю базу данных, просто удалите таблицы своего приложения перед запуском syncdb
Это будет выполнено для вас в одной строке (для каждого приложения):
python manage.py sqlclear appname | python manage.py dbshell
Первая команда проверит ваше приложение и сгенерирует необходимый SQL для удаления таблиц. Этот вывод затем передается в dbshell для его выполнения.
После этого запустите syncdb, чтобы воссоздать таблицы:
python manage.py syncdb
Ключ должен использовать --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/
Если вам нужна возможность - как и я - действительно начать с новой базы данных, не задавая этот вопрос суперпользователя, то вы можете просто отменить регистрацию обработчика сигнала, который задает этот вопрос. Проверьте в самом низу файла:
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 достаточно умен, чтобы сначала делать что-то свое, а потом мое, если я захочу испортить их настройки? Дайте мне знать, если узнаете.:-)
Я преодолел эту функцию, используя юг
Это должно быть для любого разработчика Django.
South - это инструмент, предназначенный для переноса изменений на действующий сайт без разрушения информации или структуры базы данных. Полученные изменения могут быть отслежены югом и с помощью сгенерированных файлов Python могут выполнять те же действия с альтернативной базой данных.
Во время разработки я использую этот инструмент для отслеживания изменений в моей базе данных и внесения изменений в базу данных без необходимости сначала ее уничтожать.
- easy_install юг
- Добавить "юг" в ваши установленные приложения
Предлагая первый раз запустить юг на приложение.
$ 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
и вы хотите создать и администрировать пользователя с паролем администратора при каждом запуске ./manage.py migrate
с нуля. Я также предполагаю, что автоматическое создание пользователей с правами администратора требуется только в среде разработчиков, а не в рабочей среде.
Добавьте следующий код в 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')
Также добавьте следующую ссылку на конфигурацию приложения в приложениях example_app/__init__.py
:
# example_app/__init__.py
default_app_config = 'example_app.config.ExampleAppConfig'
Где default_app_config - это строковый путь Python к AppConfig
подкласс, как упомянуто здесь.
manage.py reset
Команда сбросит вашу базу данных, не уничтожая созданного вами суперпользователя. Однако данные необходимо повторно импортировать.
Начиная с 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)]
Вы можете использовать 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
(Джанго <1,7) или ./manage.py migrate
(Django >= 1.7), и он автоматически создаст суперпользователя или обновит существующий для вас.
Вам больше не предлагается создавать суперпользователя.
Я решил создать такой скрипт на 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: Обязательно остановите ваш (тестирующий) сервер, на котором находится вышеупомянутая база данных, перед запуском этого скрипта!
Посмотрите на dumpdata
команда управления. Например:
python manage.py dumpdata > initial_data.json
Если этот файл называется приспособлением, называется initial_data
(.xml или.json), затем syncdb
Команда подберет его и заполнит ваши таблицы соответственно. Он по-прежнему спросит вас, хотите ли вы создать пользователя, но я полагаю, что вы можете смело ответить "нет", после чего он будет заполнять базу данных на основе вашего устройства.
Более подробную информацию об этом можно найти в документации.
Разработка с 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')
Если вы предпочитаете вводить инициализирующий код непосредственно в исходный файл 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
Я просто показываю здесь код создания пользователя, но вы можете улучшить этот код по своему усмотрению.
Мое решение этого состояло в том, чтобы просто не удалять эти таблицы аутентификации при стирании моей базы данных.
Я использую sqlite в качестве базы данных разработчика. После изменения классов модели просто удалите соответствующие таблицы с помощью диспетчера sqlite (плагин Firefox, открытый для проверки данных в любом случае) и запустите manage.py syncdb
воссоздать то, чего не хватает.