Come automatizzare createuperuser su django?


128

Voglio esecuzione automatica manage.py createsuperusersu djangoma cuciture che non c'è modo di impostare una password di default.

Come posso ottenerlo? Deve essere indipendente dal database django.


1
hai pensato di salvare il tuo superutente creato su un dispositivo e caricarlo utilizzando manage.py?
turbotux

1
@turbotux La risposta di Hendrik F ha un approccio simile a quello che suggerisci, con l'ulteriore capacità di leggere i valori (login, password ...) da env vars (o filesystem, ...). Consiglio vivamente di andare in questa direzione invece degli script python ad-hoc, che hanno problemi quando riavvii l'applicazione.
Annuncio N

Risposte:


145

Se fai riferimento direttamente a Utente , il tuo codice non funzionerà nei progetti in cui l'impostazione AUTH_USER_MODEL è stata modificata in un modello utente diverso. Un modo più generico per creare l'utente sarebbe:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@myproject.com', 'password')" | python manage.py shell

RISPOSTA ORIGINALE

Ecco una semplice versione dello script per creare un superutente:

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

2
super utile quando si tenta di creare un superutente in heroku e la rete blocca la porta 5000
Vic

4
Vorrei eliminare il superutente esistente, quindi questo è valido per ogni build: echo "from django.contrib.auth.models import User; User.objects.filter(email='admin@example.com').delete(); User.objects.create_superuser('admin@example.com', 'admin', 'nimda')" | python manage.py shell
Montaro

12
Personalmente non penso che eliminare l'utente su ogni build sia una buona idea. Rischi di eliminare involontariamente i record associati tramite un'eliminazione a cascata. Un'opzione più sicura è semplicemente il salvataggio se l'utente esiste già (o aggiornare il record utente esistente).
Will

6
Almeno su Django 1.11. l'ordine degli argomenti è ("username", "email", "pass"), non ("email", "username", "pass"). Vedi: docs.djangoproject.com/en/1.11/ref/contrib/auth/…
np8

3
from django.contrib.auth.models import Usernon lavora più. Usa questo: from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@myproject.com', 'my secure password')
dcalde

49

Stavo cercando una risposta a questo io stesso. Ho deciso di creare un comando Django che estende il createsuperusercomando di base ( GitHub ):

from django.contrib.auth.management.commands import createsuperuser
from django.core.management import CommandError


class Command(createsuperuser.Command):
    help = 'Crate a superuser, and allow password to be provided'

    def add_arguments(self, parser):
        super(Command, self).add_arguments(parser)
        parser.add_argument(
            '--password', dest='password', default=None,
            help='Specifies the password for the superuser.',
        )

    def handle(self, *args, **options):
        password = options.get('password')
        username = options.get('username')
        database = options.get('database')

        if password and not username:
            raise CommandError("--username is required if specifying --password")

        super(Command, self).handle(*args, **options)

        if password:
            user = self.UserModel._default_manager.db_manager(database).get(username=username)
            user.set_password(password)
            user.save()

Esempio di utilizzo:

./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'

Ciò ha il vantaggio di supportare ancora l'uso del comando predefinito, consentendo anche l'uso non interattivo per specificare una password.


4
Questa dovrebbe essere la risposta più votata (e accettata).
bruno desthuilliers

Vorrei che anche il valore predefinito createsuperuseravesse questo --passwordcampo
shadi

1
È possibile aggiungere un esempio di utilizzo:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'
shadi

2
come è createsuperuser2mappato a questa classe, funzione
Srinath Ganesh

2
@SrinathGanesh dai un'occhiata a docs.djangoproject.com/en/1.8/howto/custom-management-commands È necessario assegnare un nome al file python createsuperuser2.pye inserirlo nella struttura di directory definita dal collegamento sopra.
ElectRocnic

43

Uso './manage.py shell -c':

./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', 'admin@example.com', 'adminpass')"

Questo non usa un eco extra, questo ha il vantaggio che puoi passarlo a un contenitore docker per l'esecuzione. Senza la necessità di usare sh -c "..." che ti porta a citare la fuga dall'inferno.

E ricorda che prima viene il nome utente, poi l'email.

Se si dispone di un modello utente personalizzato, è necessario importarlo e non auth.models.User


1
Ha funzionato per me. Grazie!
TimH - Codidact

Non sembra funzionare per me, vedo:AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
Brodan

quando si dispone di un modello utente personalizzato come users.User è necessario importare da quello e non daauth.User
yvess

30

Suggerirei di eseguire una migrazione dei dati , quindi quando le migrazioni vengono applicate al progetto, viene creato un superutente come parte delle migrazioni. Il nome utente e la password possono essere impostati come variabili di ambiente. Ciò è utile anche quando si esegue un'app in un contenitore (vedere questo thread come esempio)

La tua migrazione dei dati sarebbe quindi simile a questa:

import os
from django.db import migrations

class Migration(migrations.Migration):
    dependencies = [
        ('<your_app>', '<previous_migration>'),
    ] # can also be emtpy if it's your first migration

    def generate_superuser(apps, schema_editor):
        from django.contrib.auth.models import User

        DJANGO_DB_NAME = os.environ.get('DJANGO_DB_NAME', "default")
        DJANGO_SU_NAME = os.environ.get('DJANGO_SU_NAME')
        DJANGO_SU_EMAIL = os.environ.get('DJANGO_SU_EMAIL')
        DJANGO_SU_PASSWORD = os.environ.get('DJANGO_SU_PASSWORD')

        superuser = User.objects.create_superuser(
            username=DJANGO_SU_NAME,
            email=DJANGO_SU_EMAIL,
            password=DJANGO_SU_PASSWORD)

        superuser.save()

    operations = [
        migrations.RunPython(generate_superuser),
    ]

Spero che aiuti!

EDIT : Alcuni potrebbero sollevare la domanda su come impostare queste variabili d'ambiente e renderle consapevoli di Django. Ci sono molti modi ed è stato risposto in altri post SO, ma proprio come un rapido puntatore, creare un .envfile è una buona idea. Potresti quindi usare il pacchetto python-dotenv , ma se hai configurato un ambiente virtuale con pipenv, imposterà automaticamente gli envvars nel tuo .envfile. Allo stesso modo, l'esecuzione della tua app tramite docker-compose può leggere il tuo .envfile.


1
SUGGERIMENTO: considera questo approccio . Questa è una risposta di alta qualità: sfrutta naturalmente le funzionalità integrate di Django per rispondere alla domanda invece di echeggiare script python ad-hoc, inoltre affronta naturalmente il problema più grande della risposta accettata (una migrazione viene applicata solo una volta su una distribuzione , quindi l'utente viene creato una sola volta). Funziona magnificamente in un contesto di container.
Annuncio N

Questa sembra un'ottima risposta. Non so ancora dove si inserisce questo pezzo di codice nel progetto?
Pablo Ruiz Ruiz

Dovrebbe essere nella cartella delle migrazioni, ad esempio root/⁨mysite⁩/myapp⁩/⁨migrations⁩- se leggi i documenti, spiega come puoi creare una migrazione vuota e modificarlapython manage.py makemigrations --empty yourappname
Hendrik F

Perché hai bisogno di DJANGO_DB_NAME? non viene mai utilizzato.
thoroc

Dovresti menzionare di aggiungere quanto segue per caricare i file .env nel settings.pyfile:python # loading .env from dotenv import load_dotenv from pathlib import Path env_path = Path('.', '.env') load_dotenv(dotenv_path=env_path)
thoroc

23

Come di Django 3.0 è possibile utilizzare di default createsuperuser --noinputdei comandi e impostare tutti i campi richiesti (tra cui password) come variabili di ambiente DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAILper esempio. --noinputla bandiera è obbligatoria.

Questo proviene dai documenti originali: https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-createsuperuser

e ho appena controllato - funziona. Ora puoi esportare facilmente quelle variabili d'ambiente e aggiungerle createsuperuserai tuoi script e pipeline.


14

Potresti scrivere un semplice script Python per gestire l'automazione della creazione di superutente. Il Usermodello è solo un normale modello Django, quindi seguirai il normale processo di scrittura di uno script Django autonomo. Ex:

import django
django.setup()

from django.contrib.auth.models import User

u = User(username='unique_fellow')
u.set_password('a_very_cryptic_password')
u.is_superuser = True
u.is_staff = True
u.save()

Puoi anche passare createsuperuseralcune opzioni, vale a dire --noinpute --username, che ti consentirebbero di creare automaticamente nuovi superutenti, ma non saranno in grado di accedere finché non imposti una password per loro.


2
Va bene cretesuperuser, ma allora come impostare la password? Mi piacerebbe farlo all'interno di uno script bash ...
caneta

10

Risposta attuale più votata:

  • Elimina l'utente se esiste e, come indicato da @Groady nei commenti, rischi di eliminare involontariamente i record associati tramite un'eliminazione a cascata.
  • Controlla l'esistenza di un superutente filtrando per posta, quindi se due superutenti hanno la stessa posta, Dio sa quale cancella.
  • È complicato aggiornare i parametri dello script: nome utente, password e posta.
  • Non registra ciò che ha fatto.

Una versione migliorata sarebbe:

USER="admin"
PASS="super_password"
MAIL="admin@mail.com"
script="
from django.contrib.auth.models import User;

username = '$USER';
password = '$PASS';
email = '$MAIL';

if User.objects.filter(username=username).count()==0:
    User.objects.create_superuser(username, email, password);
    print('Superuser created.');
else:
    print('Superuser creation skipped.');
"
printf "$script" | python manage.py shell

2
Molto più pulito (migliore) della risposta accettata. Si potrebbe anche aver usato: if not User.objects.filter(username = username).exists(),
Philippe Fanaro

5
DJANGO_SUPERUSER_USERNAME=testuser \
DJANGO_SUPERUSER_PASSWORD=testpass \
python manage.py createsuperuser --noinput

Documentazione per il comando createuser


Questa è la soluzione più semplice. Ma puoi sovrascrivere il noinputflag con altri parametri:DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email admin@email.com --noinput
dannydedog,

1

Ho usato Tk421 one liner ma ho ricevuto un messaggio di errore come: 1) Penso di utilizzare una versione successiva di Django (1.10) Manager isn't available; 'auth.User' has been swapped for 'users.User'2) l'ordine dei parametri per create_superuser era sbagliato.

Quindi l'ho sostituito con:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(email='admin@example.com', is_superuser=True).delete(); User.objects.create_superuser('admin', 'admin@example.com', 'nimda')" | python manage.py shell

e quello che mi fa davvero piacere è che funziona anche su una distribuzione heroku:

heroku run echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(email='admin@example.com', is_superuser=True).delete(); User.objects.create_superuser('admin', 'admin@example.com', 'nimda')" | python manage.py shell

Questo funzionerà bene e ripetutamente. Lo sto usando all'inizio di un progetto, quindi non preoccuparti delle terribili eliminazioni a cascata che potrebbero verificarsi in seguito.

Ho rivisitato dopo alcuni problemi con l'esecuzione di questo all'interno di local () da fabric. quello che sembrava accadere è che il simbolo della pipa significa che veniva interpretato localmente piuttosto che su heroku. Per ordinare questo ho racchiuso il comando tra virgolette. Quindi ho dovuto utilizzare virgolette doppie triple per le stringhe python all'interno delle virgolette singole dell'intero comando python.

heroku run "echo 'from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.filter(email="""admin@example.com""", is_superuser=True).delete(); User.objects.create_superuser("""admin""", """admin@example.com""", """nimda""")' | python manage.py shell"

1

Una soluzione basata su Adam Charnock approccio s' sopra è disponibile come pacchetto Python ormai. Sono necessari tre passaggi:

  1. Installare: pip install django-createsuperuserwithpassword

  2. Attivare: INSTALLED_APPS += ("django_createsuperuserwithpassword", )

  3. Applicare:

    python manage.py createsuperuserwithpassword \
            --username admin \
            --password admin \
            --email admin@example.org \
            --preserve

Questo è tutto.



0

Questo piccolo script python potrebbe creare un utente normale o un superutente

#!/usr/bin/env python

import os
import sys
import argparse
import random
import string
import django


def main(arguments):

    parser = argparse.ArgumentParser()
    parser.add_argument('--username', dest='username', type=str)
    parser.add_argument('--email', dest='email', type=str)
    parser.add_argument('--settings', dest='settings', type=str)
    parser.add_argument('--project_dir', dest='project_dir', type=str)
    parser.add_argument('--password', dest='password', type=str, required=False)
    parser.add_argument('--superuser', dest='superuser', action='store_true', required=False)

    args = parser.parse_args()

    sys.path.append(args.project_dir)
    os.environ['DJANGO_SETTINGS_MODULE'] = args.settings
    from django.contrib.auth.models import User
    django.setup()

    username = args.username
    email = args.email
    password = ''.join(random.sample(string.letters, 20)) if args.password is None else args.password
    superuser = args.superuser 

    try:
        user_obj = User.objects.get(username=args.username)
        user_obj.set_password(password)
        user_obj.save()
    except User.DoesNotExist:
    if superuser:
            User.objects.create_superuser(username, email, password)
    else:
        User.objects.create_user(username, email, password)

    print password


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))

--superuser e --password non sono obbligatori.

Se --superuser non è definito, verrà creato un utente normale Se --password non è definito, verrà generata una password casuale

    Ex : 
        /var/www/vhosts/PROJECT/python27/bin/python /usr/local/sbin/manage_dja_superusertest.py --username USERNAME --email TEST@domain.tld --project_dir /var/www/vhosts/PROJECT/PROJECT/ --settings PROJECT.settings.env 

0

Questo è ciò che ho messo insieme per Heroku post_deploy e una variabile app.json predefinita :

if [[ -n "$CREATE_SUPER_USER" ]]; then
    echo "==> Creating super user"
    cd /app/example_project/src
    printf "from django.contrib.auth.models import User\nif not User.objects.exists(): User.objects.create_superuser(*'$CREATE_SUPER_USER'.split(':'))" | python /app/example_project/manage.py shell
fi

Con questo puoi avere una singola variabile env:

CREATE_SUPER_USER=admin:admin@example.com:password

Mi piace l' opzione shell --command , ma non sono sicuro di come ottenere il carattere di nuova riga nello script dei comandi. Senza la nuova riga l' ifespressione restituisce un errore di sintassi.


0

Vai al prompt dei comandi e digita:

C:\WINDOWS\system32>pip install django-createsuperuser
Collecting django-createsuperuser
  Downloading https://files.pythonhosted.org/packages/93/8c/344c6367afa62b709adebee039d09229675f1ee34d424180fcee9ed857a5/django-createsuperuser-2019.4.13.tar.gz
Requirement already satisfied: Django>1.0 in c:\programdata\anaconda3\lib\site-packages (from django-createsuperuser) (2.2.1)
Requirement already satisfied: setuptools in c:\programdata\anaconda3\lib\site-packages (from django-createsuperuser) (41.0.1)
Requirement already satisfied: sqlparse in c:\programdata\anaconda3\lib\site-packages (from Django>1.0->django-createsuperuser) (0.3.0)
Requirement already satisfied: pytz in c:\programdata\anaconda3\lib\site-packages (from Django>1.0->django-createsuperuser) (2018.7)
Building wheels for collected packages: django-createsuperuser
  Running setup.py bdist_wheel for django-createsuperuser ... done
  Stored in directory: C:\Users\Arif Khan\AppData\Local\pip\Cache\wheels\0c\96\2a\e73e95bd420e844d3da1c9d3e496c92642a4f2181535440db2
Successfully built django-createsuperuser
Installing collected packages: django-createsuperuser

se non viene eseguita la migrazione, vai alla cartella dell'applicazione django ed esegui quanto segue

  1. python manage.py migrate
  2. python manage.py creauperuser

poi bingo.


0
python manage.py shell -c "from django.contrib.auth.models import User; \
                           User.objects.filter(username='admin1').exists() or \
                           User.objects.create_superuser('admin1',
                           'admin1@example.com', 'admin1')"

0

Con shell_plus è molto più semplice in realtà

echo "User.objects.create_superuser('test@test.com', 'test')" | python manage.py shell_plus

Come altri menzionati, con Django 3.0 puoi passare le credenziali tramite variabili d'ambiente. Tuttavia questo approccio è molto più flessibile poiché ti consente di eseguire qualsiasi altra attività più complicata come rimuovere tutti gli utenti dei test, ecc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.