Crie automaticamente um usuário administrador ao executar o Django's ./manage.py syncdb

StackOverflow https://stackoverflow.com/questions/1466827

Pergunta

Meu projeto está em desenvolvimento inicial. Eu costumo excluir o banco de dados e executar manage.py syncdb Para configurar meu aplicativo do zero.

Infelizmente, isso sempre aparece:

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

Em seguida, você fornece um nome de usuário, endereço de e -mail válido e senha. Isso é tedioso. Estou cansado de digitar test\nx@x.com\ntest\ntest\n.

Como posso pular automaticamente esta etapa e criar um usuário programaticamente ao executar manage.py syncdb ?

Foi útil?

Solução

Eu sei que a pergunta já foi respondida, mas ...

Uma abordagem muito mais simples é despejar os dados do módulo de autenticação em um arquivo JSON depois que o superusuário for criado:

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

Você também pode despejar os dados de sessões:

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

Você pode anexar as informações da sessão ao dump do módulo de autenticação (e provavelmente aumentar o Expire_date para que ele não expire ... nunca ;-).

A partir de então, você pode usar

/manage.py syncdb --noinput

Para carregar o superusuário e sua sessão ao criar o banco de dados sem prompt interativo perguntando sobre um superusuário.

Outras dicas

Em vez de excluir todo o seu banco de dados, basta excluir as tabelas do seu aplicativo antes de executar o SyncDB

Isso o realizará para você em uma única linha (por aplicativo):

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

O primeiro comando analisará seu aplicativo e gerará o SQL necessário para soltar as tabelas. Esta saída é então canalizada para o DBshell para executá -la.

Depois de terminar, execute seu SyncDB para recriar as mesas:

python manage.py syncdb

A chave é usar --noinput no momento do syncdb e depois use isso one liner para criar superusuário

echo "from django.contrib.auth.models import User; User.objects.create_superuser('myadmin', 'myemail@example.com', 'hunter2')" | python manage.py shell

Crédito: http://source.mihelac.org/2009/10/23/django-avoiding-typing-password-for-superuser/

Se você deseja a habilidade-como eu-realmente começar com um novo banco de dados sem receber essa pergunta sobre o superusuário, você pode apenas registrar o manipulador de sinal que faz essa pergunta. Confira a parte inferior do arquivo:

django/contrib/auth/management/__init__.py

Para ver como o registro da função do superusuário é executado. Descobri que poderia reverter esse registro e nunca me fizeram a pergunta durante o "SyncDB", se eu colocasse esse código no meu "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")

Não tenho certeza de como garantir que este código seja executado depois o código do Django que faz o registro. Eu pensei que isso dependeria se o seu aplicativo ou o aplicativo django.Contrib.Auth é mencionado primeiro em instalado_apps, mas parece funcionar para mim, independentemente da ordem em que os coloquei. Talvez eles tenham feito em ordem alfabética e eu sou Sorte que o nome do meu aplicativo começa com uma carta mais tarde que "D"? Ou o Django é inteligente o suficiente para fazer suas próprias coisas primeiro, depois o meu, caso eu queira sujar com suas configurações? Deixe -me saber se você descobrir. :-)

Eu superei esse recurso usando sul

É um deve ter para qualquer desenvolvedor de Django.

South é uma ferramenta projetada para ajudar a migrar as alterações para o site ao vivo sem destruir informações ou estrutura de banco de dados. As alterações resultantes podem ser rastreadas pelo sul e o uso dos arquivos Python gerados - podem executar as mesmas ações em um banco de dados alternativo.

Durante o desenvolvimento, eu uso esta ferramenta para rastrear as alterações do meu banco de dados - e para fazer uma alteração no banco de dados sem a necessidade de destruí -lo primeiro.

  1. Easy_install para o sul
  2. Adicione 'South' aos seus aplicativos instalados

Propondo primeira vez em um aplicativo em um aplicativo.

$ python manage.py schemamigration appname --init

Isso iniciará a detecção de esquema nesse aplicativo.

$ python manage.py migrate appname

Isso aplicará as mudanças do modelo

  • O banco de dados terá os novos modelos.

Mudando um modelo após a primeira corrida

$ python manage.py schemamigration appname --auto

$ python manage.py migrate appname


Os modelos terão alterado - os dados não são destruídos. Além disso, o sul faz muito mais ...

Nota: Desde a versão 1.7 syncdb comando é descontinuada. Usar migrate em vez de.

Também o Django 1.7 introduzido AppConfig como meios de personalizar o processo de inicialização dos aplicativos.

Assim como Django 1.7, a maneira mais simples de alcançar o que você deseja é empregar um AppConfigSubclasse.

Vamos dizer, você tem o seu próprio example_app que é adicionado ao seu INSTALLED_APPS E você quer criar e admin usuário com admin Senha sempre que você executa ./manage.py migrate do princípio. Presumo também que a criação automática de usuários do administrador é necessária apenas em Dev meio ambiente - não em Produção.

Adicione o seguinte código a 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)

Adicione também a seguinte referência à configuração do aplicativo dentro de aplicativos example_app/__init__.py:

# example_app/__init__.py

default_app_config = 'example_app.apps.ExampleAppConfig'

Onde o default_app_config é um caminho de string python para o AppConfig subclasse como mencionado aqui.

o manage.py reset O comando redefinirá seu banco de dados sem destruir seu super usuário criado. No entanto, os dados precisam ser reimportados.

Você pode usar Django-Finalware Para fazer isso por você. Basta adicionar finalware para o seu INSTALLED_APPS e inclua o seguinte em seu 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'

Então apenas corra ./manage.py syncdb (Django <1,7) ou ./manage.py migrate (Django> = 1.7) e criará automaticamente um superusuário ou atualizará o existente para você.

Você nunca mais é solicitado a criar um superusuário.

Como Django 1.7, a maneira sugerida de preencher o banco de dados é através de migrações de dados. Para criar uma migração de dados para criar o administrador, você deve primeiro criar uma migração vazia:

./manage.py makemigrations --empty myapp --name create-superuser

Isso criará uma migração vazia em myapp/migrations/000x__create-superuser.py. Edite o arquivo para fazer parecer assim:

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

Eu resolvi a criação de um script python como este para redefinir todas as minhas coisas [versão atualizada] [1.8 também]:

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

Ele funciona como um encanto!

PS: Certifique -se de interromper seu servidor (testando), onde o DB acima está no comando antes de executar este script!

Dê uma olhada no dumpdata Comando de gerenciamento. Por exemplo:

python manage.py dumpdata > initial_data.json

Se este arquivo, chamado de acessório, for nomeado initial_data (.xml ou .json), então o syncdb O comando o pegará e preencherá suas tabelas de acordo. Ele ainda perguntará se você deseja criar um usuário, mas acredito que você pode responder com segurança "não", após o que ele preencherá o banco de dados com base no seu acessório.

Mais informações sobre isso podem ser encontradas no documentos.

Desenvolvendo com SQLite. Limpe o banco de dados excluindo o arquivo. Carregar administrador de acessórios.

alteração gerencial.py (django 1.4):

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

Minha solução para isso foi simplesmente não excluir essas tabelas de autenticação ao eliminar meu banco de dados.

Se você preferir digitar o código de inicialização diretamente no arquivo de origem Python, este código modificado gerencia.py pode ajudar (e obrigado pelo pequeno código do 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

Estou apenas mostrando o código de criação do usuário aqui, mas você pode aprimorar mais esse código conforme desejar.

Estou usando o SQLite como um banco de dados dev. Depois de mudar as aulas de modelo, basta soltar as tabelas correspondentes com Gerente SQLite (um plugin do Firefox, aberto para inspecionar os dados de qualquer maneira) e executar manage.py syncdb para recriar o que está faltando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top