startapp - Crear automáticamente un usuario administrador al ejecutar./manage.py syncdb de Django
python manage.py startapp (15)
Mi proyecto está en desarrollo temprano. Con frecuencia manage.py syncdb
la base de datos y ejecuto manage.py syncdb
para configurar mi aplicación desde cero.
Desafortunadamente, esto siempre 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):
Luego, debe proporcionar un nombre de usuario, una dirección de correo electrónico válida y una contraseña. Esto es tedioso Me estoy cansando de escribir test/[email protected]/ntest/ntest/n
.
¿Cómo puedo omitir automáticamente este paso y crear un usuario programáticamente cuando manage.py syncdb
?
Desarrollando con sqlite. Borre la base de datos borrando el archivo. Cargar administrador de accesorios.
cambiar manage.py (django 1.4):
# hack to prevent admin promt
if len(sys.argv) == 2 and sys.argv[1] == ''syncdb'':
sys.argv.append(''--noinput'')
Desde Django 1.7, la forma sugerida de poblar la base de datos es a través de migraciones de datos. Para crear una migración de datos para crear el administrador, primero debe crear una migración vacía:
./manage.py makemigrations --empty myapp --name create-superuser
Esto creará una migración vacía en myapp/migrations/000x__create-superuser.py
. Edite el archivo para que se vea así:
# -*- 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=''[email protected]'')
class Migration(migrations.Migration):
dependencies = [(''myapp'', ''000y_my-previous-migration-file''),]
operations = [migrations.RunPython(create_superuser)]
Eche un vistazo al comando de administración de dumpdata
. Por ejemplo:
python manage.py dumpdata > initial_data.json
Si este archivo, llamado accesorio, se llama initial_data
(.xml o .json), entonces el comando syncdb
lo recogerá y rellenará las tablas en consecuencia. Todavía le preguntará si desea crear un usuario, pero creo que puede responder "no" de manera segura, luego de lo cual completará la base de datos en función de su dispositivo.
Se puede encontrar más información sobre esto en los docs .
El manage.py reset
su base de datos sin destruir a su súper usuario creado. Sin embargo, es necesario volver a importar los datos.
En lugar de eliminar toda la base de datos, simplemente elimine las tablas de su aplicación antes de ejecutar el syncdb
Esto lo logrará en una sola línea (por aplicación):
python manage.py sqlclear appname | python manage.py dbshell
El primer comando mirará su aplicación y generará el SQL requerido para soltar las tablas. Esta salida se canaliza a dbshell para ejecutarla.
Una vez hecho esto, ejecute su syncdb para recrear las tablas:
python manage.py syncdb
Estoy usando sqlite como una base de datos de desarrollo. Después de cambiar las clases de modelo, simplemente suelte las tablas correspondientes con el administrador de sqlite (un complemento de Firefox, abierto para inspeccionar los datos de todos modos) y ejecute manage.py syncdb
para recrear lo que falta.
He resuelto crear un script de python como este para restablecer todas mis cosas [versión actualizada] [1.8 también]:
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="[email protected]")
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()
¡funciona a las mil maravillas!
PD: ¡Asegúrate de detener tu servidor (de prueba) donde db anterior está a cargo antes de ejecutar este script!
He superado esta función usando south
Es imprescindible para cualquier desarrollador django.
South es una herramienta diseñada para ayudar a migrar los cambios al sitio en vivo sin destruir la información o la estructura de la base de datos. Los cambios resultantes pueden ser rastreados por el sur y utilizando los archivos python generados; puede realizar las mismas acciones en una base de datos alternativa.
Durante el desarrollo, utilizo esta herramienta para hacer un seguimiento de los cambios en mi base de datos y para realizar un cambio en la base de datos sin la necesidad de destruirla primero.
- easy_install sur
- Agrega ''sur'' a tus aplicaciones instaladas
Proponer correr por primera vez del sur en una aplicación.
$ python manage.py schemamigration appname --init
Esto iniciará la detección del esquema en esa aplicación.
$ python manage.py migrate appname
Esto aplicará los cambios del modelo
- La base de datos tendrá los nuevos modelos.
Cambiar un modelo después de la primera ejecución
$ python manage.py schemamigration appname --auto
$ python manage.py migrate appname
Los modelos habrán cambiado; los datos no se destruirán. Además, South hace mucho más ...
La clave es usar --noinput
en el momento de syncdb y luego usar este one liner
para crear superusuario
echo "from django.contrib.auth.models import User; User.objects.create_superuser(''myadmin'', ''[email protected]'', ''hunter2'')" | python manage.py shell
Crédito: http://source.mihelac.org/2009/10/23/django-avoiding-typing-password-for-superuser/
Mi solución a esto fue simplemente no eliminar esas tablas de autenticación al borrar mi base de datos.
Nota: desde la versión 1.7 el comando syncdb
está en deprecated . Use migrate
instead .
Además, Django 1.7 introdujo AppConfig como medio para personalizar el proceso de inicialización de las aplicaciones.
Por lo tanto, desde Django 1.7 la forma más sencilla de lograr lo que desea es emplear una subclase de AppConfig
.
Supongamos que tiene su propia example_app
que se agrega a su INSTALLED_APPS
y desea crear y administrar el usuario con contraseña de administrador siempre que ejecute ./manage.py migrate
desde cero. También asumo que la creación automática de usuarios administradores solo se requiere en el entorno de desarrollo, no en producción .
Agregue el siguiente código a 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, ''[email protected]'', 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'')
También agregue la siguiente referencia a la configuración de la aplicación dentro de las aplicaciones example_app/__init__.py
:
# example_app/__init__.py
default_app_config = ''example_app.config.ExampleAppConfig''
Donde default_app_config es una ruta de Python de cadena a la subclase AppConfig
como se menciona here .
Puede usar django-finalware para hacer esto por usted. Simplemente agregue el finalware
a su INSTALLED_APPS
e incluya lo siguiente en su settings.py
:
SITE_SUPERUSER_USERNAME = ''myadmin''
SITE_SUPERUSER_EMAIL = ''[email protected]''
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''
A continuación, ejecute ./manage.py syncdb
(Django <1.7) o ./manage.py migrate
(Django> = 1.7), y creará automáticamente un superusuario o actualizará el existente por usted.
Nunca más se le pedirá que cree un superusuario.
Sé que la pregunta ya ha sido respondida, pero ...
Un enfoque mucho más simple es volcar los datos del módulo de autenticación en un archivo json una vez que se haya creado el superusuario:
./manage.py dumpdata --indent=2 auth > initial_data.json
También puede volcar los datos de las sesiones:
./manage.py dumpdata --indent=2 sessions
A continuación, puede agregar la información de la sesión al volcado del módulo de autenticación (y probablemente aumente la fecha de vencimiento para que no caduque ... nunca ;-).
A partir de entonces, puedes usar
/manage.py syncdb --noinput
cargar el superusuario y su sesión al crear la base de datos sin un aviso interactivo que le pregunte sobre un superusuario.
Si desea la capacidad, como yo lo hago, de comenzar realmente con una nueva base de datos sin que le hagan esa pregunta al superusuario, entonces puede simplemente anular el registro del manejador de señal que realiza esa pregunta. Mira la parte inferior del archivo:
django/contrib/auth/management/__init__.py
para ver cómo se realiza el registro de la función de superusuario. Descubrí que podía revertir este registro, y nunca me hicieron la pregunta durante "syncdb", si coloqué este código en mi "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")
No estoy seguro de cómo garantizar que este código se ejecute después del código de Django que realiza el registro. Pensé que eso dependería de si su aplicación o la aplicación django.contrib.auth se menciona primero en INSTALLED_APPS, pero parece funcionar para mí independientemente del orden en el que las puse. Quizás estén hechas alfabéticamente y estoy ¿Suerte que el nombre de mi aplicación comienza con una letra posterior a "d"? ¿O es que Django es lo suficientemente inteligente como para hacer sus propias cosas primero, y luego las mías en caso de que quiera ensuciar con sus configuraciones? Avísame si lo descubres. :-)
Si prefiere escribir el código de inicialización directamente en el archivo fuente de Python, este código modificado manage.py podría ayudar (¡y gracias por el pequeño código de 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 = ''[email protected]''
admin_password = ''superuser_password''
additional_users = [
[''tempuser'', ''[email protected]'', ''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
Solo estoy mostrando el código de creación del usuario aquí, pero puede mejorar este código más a gusto.