Development Tip

Django의 ./manage.py syncdb를 실행할 때 자동으로 관리자 사용자 생성

yourdevel 2020. 10. 6. 19:28
반응형

Django의 ./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어떻게해야합니까?


질문에 대한 답변은 이미 알고 있지만 ...

훨씬 더 간단한 방법은 수퍼 유저가 생성 된 후 인증 모듈 데이터를 json 파일로 덤프하는 것입니다.

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

세션 데이터를 덤프 할 수도 있습니다.

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

그런 다음 세션 정보를 인증 모듈 덤프에 추가 할 수 있습니다 (그리고 만료되지 않도록 expire_date를 늘릴 수 있습니다 ... 절대 ;-).

그때부터 다음을 사용할 수 있습니다.

/manage.py syncdb --noinput

수퍼 유저에 대해 묻는 대화식 프롬프트없이 db를 만들 때 수퍼 유저와 그의 세션을로드합니다.


전체 데이터베이스를 삭제하는 대신 syncdb를 실행하기 전에 앱의 테이블을 삭제하면됩니다.

이렇게하면 앱당 한 줄로 수행 할 수 있습니다.

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

첫 번째 명령은 앱을보고 테이블을 삭제하는 데 필요한 SQL을 생성합니다. 이 출력은 dbshell로 파이프되어 실행됩니다.

완료되면 syncdb를 실행하여 테이블을 다시 만듭니다.

python manage.py syncdb

핵심은 --noinputsyncdb시 사용하고 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

수퍼 유저 기능 등록이 수행되는 방법을 확인합니다. 이 코드를 "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는 먼저 자체 작업을 수행 할 수있을만큼 똑똑한가요? 알아 내면 알려주세요. :-)


이 기능은 남쪽을 사용하여 극복했습니다

모든 장고 개발자에게는 필수입니다.

South는 정보 나 데이터베이스 구조를 파괴하지 않고 변경 사항을 라이브 사이트로 마이그레이션 할 수 있도록 설계된 도구입니다. 결과 변경 사항은 남쪽으로 추적 할 수 있으며 생성 된 파이썬 파일을 사용하여 대체 데이터베이스에서 동일한 작업을 수행 할 수 있습니다.

개발 중에이 도구를 사용하여 데이터베이스 변경 사항을 추적하고 먼저 데이터베이스를 파괴 할 필요없이 데이터베이스를 변경합니다.

  1. easy_install 남쪽
  2. 설치된 앱에 'south'추가

앱에서 처음으로 남쪽을 달리는 것을 제안합니다.

$ python manage.py schemamigration appname --init

그러면 해당 앱에서 스키마 감지가 시작됩니다.

$ python manage.py migrate appname

모델 변경 사항이 적용됩니다.

  • 데이터베이스에는 새 모델이 있습니다.

첫 번째 실행 후 모델 변경

$ python manage.py schemamigration appname --auto

$ python manage.py migrate appname


모델이 변경됩니다-데이터가 파괴되지 않습니다. Plus South는 훨씬 더 많은 일을합니다 ...


참고 : 버전 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는 여기에AppConfig 언급 된 하위 클래스에 대한 문자열 Python 경로 입니다.


manage.py reset명령은 생성 된 수퍼 유저를 파괴하지 않고 데이터베이스를 재설정합니다. 그러나 데이터를 다시 가져와야합니다.


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)을 실행하면 자동으로 수퍼 유저를 생성하거나 기존 사용자를 업데이트합니다.

더 이상 수퍼 유저를 만들라는 메시지가 표시되지 않습니다.


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

나는 내 모든 물건을 재설정하기 위해 이와 같은 파이썬 스크립트를 만들기로 결정했다 [업데이트 된 버전] [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()

그것은 매력처럼 작동합니다!

추신 :이 스크립트를 실행하기 전에 위의 db가 담당하는 서버를 중지하십시오!


dumpdata관리 명령을 살펴보십시오 . 예를 들면 :

python manage.py dumpdata > initial_data.json

If this file, called a fixture, is named initial_data (.xml or .json), then the syncdb command will pick it up and populate your tables accordingly. It will still ask you if you want to create a user, but I believe you may safely answer "no", after which point it will populate the database based on your fixture.

More info on this can be found in the docs.


Developing with sqlite. Clear database by deleting file. Load admin from fixtures.

change manage.py (django 1.4):

# hack to prevent admin promt
if  len(sys.argv) == 2 and sys.argv[1] == 'syncdb':
    sys.argv.append('--noinput')

My solution to this was to just not delete that auth tables when wiping out my database.


If you prefer to type initializing code direct into python source file, this code modified manage.py might help (and thanks for Cjkjvfnby's little code!):

#!/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

I'm just showing the user creation code here, but you can enhance this code more as you want.


I'm using sqlite as a dev database. After changing model classes, just drop the corresponding tables with sqlite manager (a firefox plugin, open to inspect the data anyways) and run manage.py syncdb to recreate what's missing.

참고URL : https://stackoverflow.com/questions/1466827/automatically-create-an-admin-user-when-running-djangos-manage-py-syncdb

반응형