Mon projet est en développement précoce. Je supprime fréquemment la base de données et exécute manage.py syncdb
pour configurer mon application à partir de zéro.
Malheureusement, cela apparaît toujours:
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):
Ensuite, vous devez fournir un nom d'utilisateur, une adresse e-mail valide et un mot de passe. C'est fastidieux. Je me lasse de taper test\[email protected]\ntest\ntest\n
.
Comment ignorer automatiquement cette étape et créer un utilisateur par programme lors de l'exécution de manage.py syncdb
?
Je sais que la question a déjà été répondue mais ...
Une approche beaucoup plus simple consiste à vider les données du module d'authentification dans un fichier json une fois le superutilisateur créé:
./manage.py dumpdata --indent=2 auth > initial_data.json
Vous pouvez également vider les données des sessions:
./manage.py dumpdata --indent=2 sessions
Vous pouvez ensuite ajouter les informations de session au vidage du module d'authentification (et probablement augmenter la date d'expiration afin qu'elle n'expire pas ... jamais ;-).
A partir de là, vous pouvez utiliser
/manage.py syncdb --noinput
pour charger le superutilisateur et sa session lors de la création de la base de données sans invite interactive vous demandant un superutilisateur.
Au lieu de supprimer l'intégralité de votre base de données, supprimez simplement les tables de votre application avant d'exécuter la syncdb
Cela le fera pour vous en une seule ligne (par application):
python manage.py sqlclear appname | python manage.py dbshell
La première commande examinera votre application et générera le SQL requis pour supprimer les tables. Cette sortie est ensuite dirigée vers la dbshell pour l'exécuter.
Une fois terminé, exécutez votre syncdb pour recréer les tables:
python manage.py syncdb
La clé est d'utiliser --noinput
au moment de la synchronisation, puis utilisez ce one liner
pour créer un superutilisateur
echo "from Django.contrib.auth.models import User; User.objects.create_superuser('myadmin', '[email protected]', 'hunter2')" | python manage.py Shell
Crédit: http://source.mihelac.org/2009/10/23/Django-avoiding-typing-password-for-superuser/
Si vous voulez que la capacité - comme je le fais - de vraiment commencer avec une nouvelle base de données sans qu'on lui pose la question du superutilisateur, alors vous pouvez simplement désenregistrer le gestionnaire de signal qui pose cette question. Découvrez tout en bas du fichier:
Django/contrib/auth/management/__init__.py
pour voir comment l'enregistrement de la fonction superutilisateur est effectué. J'ai trouvé que je pouvais annuler cet enregistrement et ne jamais me poser la question pendant "syncdb", si je plaçais ce code dans mon "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")
Je ne sais pas comment garantir l'exécution de ce code après le code Django qui fait l'enregistrement. J'avais pensé que cela dépendrait de si votre application ou le L'application Django.contrib.auth est mentionnée en premier dans INSTALLED_APPS, mais elle semble fonctionner pour moi, quel que soit l'ordre dans lequel je les ai insérées. "? Ou est Django juste assez intelligent pour faire ses propres trucs d'abord, puis le mien au cas où je voudrais foutre en l'air avec leurs paramètres? Faites le moi savoir si vous le découvrez. :-)
J'ai surmonté cette fonctionnalité en utilisant sud
C'est un must have pour tout développeur Django.
South est un outil conçu pour faciliter la migration des modifications vers le site en direct sans détruire les informations ou la structure de la base de données. Les modifications résultantes peuvent être suivies par le sud et en utilisant les fichiers python générés - peuvent effectuer les mêmes actions sur une autre base de données.
Pendant le développement, j'utilise cet outil pour suivre les modifications de ma base de données - et pour apporter une modification à la base de données sans avoir besoin de la détruire d'abord.
Proposition de la première exécution du sud sur une application.
$ python manage.py schemamigration appname --init
Cela lancera la détection de schéma sur cette application.
$ python manage.py migrate appname
Cela appliquera les changements de modèle
Modification d'un modèle après la première exécution
$ python manage.py schemamigration appname --auto
$ python manage.py migrate appname
Les modèles auront changé - les données ne seront pas détruites. De plus, le sud en fait beaucoup plus ...
Remarque: depuis la version 1.7 syncdb
, la commande est obsolète . Utilisez migrate
à la place .
Aussi Django 1.7 introduit AppConfig comme moyen de personnaliser le processus d'initialisation des applications.
Ainsi, depuis Django 1.7 le moyen le plus simple de réaliser ce que vous voulez est d'employer une sous-classe de AppConfig
.
Disons que vous avez votre propre example_app
qui est ajouté à votre INSTALLED_APPS
et vous voulez créer et admin utilisateur avec admin mot de passe à chaque fois vous courez ./manage.py migrate
de zéro. Je suppose également que la création automatique d'administrateur n'est requise que dans l'environnement dev - et non dans production.
Ajoutez le code suivant à 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')
Ajoutez également la référence suivante à la configuration des applications dans les applications example_app/__init__.py
:
# example_app/__init__.py
default_app_config = 'example_app.config.ExampleAppConfig'
Où default_app_config est une chaîne Python vers la sous-classe AppConfig
comme mentionné ici .
La commande manage.py reset
Réinitialisera votre base de données sans détruire votre super utilisateur créé. Les données doivent cependant être réimportées.
J'ai résolu de créer un script python comme celui-ci pour réinitialiser tous mes trucs [version mise à jour] [1.8 aussi]):
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()
il fonctionne comme un charme!
P.S .: Assurez-vous d'arrêter votre serveur (de test) là où la base de données ci-dessus est en charge avant d'exécuter ce script!
Depuis Django 1.7, la manière suggérée de remplir la base de données consiste à effectuer des migrations de données. Pour créer une migration de données pour la création de l'administrateur, vous devez d'abord créer une migration vide:
./manage.py makemigrations --empty myapp --name create-superuser
Cela créera une migration vide dans myapp/migrations/000x__create-superuser.py
. Modifiez le fichier pour qu'il ressemble à ceci:
# -*- 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)]
Vous pouvez utiliser Django-finalware pour le faire pour vous. Ajoutez simplement finalware
à votre INSTALLED_APPS
et incluez les éléments suivants dans votre 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'
Ensuite, exécutez simplement ./manage.py syncdb
(Django <1.7) ou ./manage.py migrate
(Django> = 1.7), et il créera automatiquement un superutilisateur ou mettra à jour celui existant pour vous.
Vous n'êtes plus invité à créer un superutilisateur.
Jetez un œil à la commande de gestion dumpdata
. Par exemple:
python manage.py dumpdata > initial_data.json
Si ce fichier, appelé fixture, est nommé initial_data
(.xml ou .json), la commande syncdb
la récupérera et remplira vos tables en conséquence. Il vous demandera toujours si vous souhaitez créer un utilisateur, mais je pense que vous pouvez répondre en toute sécurité "non", après quoi il remplira la base de données en fonction de votre appareil.
Plus d'informations à ce sujet peuvent être trouvées dans le docs .
Développer avec sqlite. Effacez la base de données en supprimant le fichier. Chargez l'administrateur à partir des appareils.
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')
Si vous préférez taper le code d'initialisation directement dans python, ce code modifié manage.py pourrait aider (et merci pour le petit code de Cjkjvfnby!):
#!/usr/bin/env python
import os
import sys
if __== "__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
Je montre juste le code de création d'utilisateur ici, mais vous pouvez améliorer ce code plus comme vous le souhaitez.
Ma solution était de ne pas supprimer les tables d'authentification lors de l'effacement de ma base de données.
J'utilise sqlite comme base de données de développement. Après avoir changé les classes de modèle, déposez simplement les tables correspondantes avec sqlite manager (un plugin firefox, ouvert pour inspecter les données de toute façon) et exécutez manage.py syncdb
pour recréer ce qui manque.