web-dev-qa-db-fra.com

Créer automatiquement un utilisateur administrateur lors de l'exécution de la syncdb ./manage.py de Django

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?

80
a paid nerd

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.

80
philgo20

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
49
Andre Miller

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/

27
user

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

16
Brandon Rhodes

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.

  1. easy_install south
  2. Ajoutez "sud" à vos applications installées

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

  • La base de données contiendra les nouveaux modèles.

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 ...

11
Glycerine

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 .

9
Archibald

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.

5
tjb

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!

3
Filippo.IOVINE

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

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.

3
un33k

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 .

2
Ryan Duffield

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')
2
Cjkjvfnby

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.

1
Kenial

Ma solution était de ne pas supprimer les tables d'authentification lors de l'effacement de ma base de données.

1
priestc

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.

0
yanchenko