Автоматично створювати користувача адміністратора під час запуску ./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.