Автоматично створювати користувача адміністратора під час запуску ./manage.py syncdb Django


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,

Відповіді:


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знайшов? У документації сказано: "У каталозі світильників кожного встановленого додатка" . Це наприклад ./eggs/Django-1.6.5-py2.7.egg/django/contrib/auth/fixtures?
user272735

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
Мені подобається така відповідь. Дякую за пропозицію!
придатний для використання

я теж, дякую! чисте рішення, вже використовуючи його для отримання чистого дампа, який я синхронізую, коли мені потрібно.
Андрей-Нікулае Петре

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 - це інструмент, призначений для перенесення змін на веб-сайт, що не працює, без руйнування інформації або структури бази даних. Отримані зміни можна відстежувати за допомогою 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Команда скине свою базу даних , не руйнуючи ваш створений привілейований користувач. Однак дані потрібно повторно імпортувати.


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), і він автоматично створить суперкористувача або оновить наявний для вас.

Вам більше не пропонують створити суперкористувача.


Якщо це було створено вами, будь ласка, додайте застереження
Erion S

Чи сумісний він з Django> = 2.0?
Дунатотатос,

@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

Якщо цей файл, який називається пристосуванням, має ім'я initial_data(.xml або .json), syncdbкоманда вибере його та заповнить ваші таблиці відповідно. Він все одно запитає вас, чи хочете ви створити користувача, але я вважаю, що ви можете сміливо відповісти "ні", після чого він заповнить базу даних на основі вашого приладу.

Більше інформації про це можна знайти в документації .


1
Ви можете додати параметр --noinput до syncdb для ярлика інтерактивного запиту, якщо у вас є інформація про суперкористувача та сеанс у вашому
Initial_data.json

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

Я просто показую тут код створення користувача, але ви можете вдосконалювати цей код як завгодно більше.


0

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.