Wie automatisiere ich createuperuser auf django?

127

Ich möchte Autorun - manage.py createsuperuserauf , djangoaber es Nähte , dass es keine Möglichkeit , ein Standard - Passwort zu setzen.

Wie kann ich das bekommen? Es muss unabhängig von der Django-Datenbank sein.

Bogdan
quelle
1
Haben Sie nur versucht, Ihrem erstellten Superuser ein Gerät zu speichern und es mit manage.py zu laden?
Turbotux
1
Die Antwort von @turbotux Hendrik F ähnelt dem, was Sie vorschlagen, mit der zusätzlichen Möglichkeit, die Werte (Login, Passwort ...) von env vars (oder Dateisystem, ...) zu lesen. Ich würde dringend empfehlen, diese Richtung anstelle der Ad-hoc-Python-Skripte einzuschlagen, die Probleme beim Neustart der Anwendung haben.
Ad N

Antworten:

143

Wenn Sie direkt auf Benutzer verweisen , funktioniert Ihr Code nicht in Projekten, in denen die Einstellung AUTH_USER_MODEL in ein anderes Benutzermodell geändert wurde. Eine allgemeinere Methode zum Erstellen des Benutzers wäre:

echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', '[email protected]', 'password')" | python manage.py shell

URSPRÜNGLICHE ANTWORT

Hier gibt es eine einfache Version des Skripts zum Erstellen eines Superusers:

echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" | python manage.py shell
Tk421
quelle
2
Super nützlich, wenn Sie versuchen, einen Superuser in Heroku zu erstellen, und Ihr Netzwerk blockiert Port 5000
Vic
4
Ich würde den vorhandenen Superuser löschen, daher gilt dies für jeden Build: echo "from django.contrib.auth.models import User; User.objects.filter(email='[email protected]').delete(); User.objects.create_superuser('[email protected]', 'admin', 'nimda')" | python manage.py shell
Montaro
12
Persönlich halte ich das Löschen des Benutzers bei jedem Build nicht für eine gute Idee. Sie riskieren das unbeabsichtigte Löschen zugehöriger Datensätze über eine Kaskadenlöschung. Eine sicherere Option besteht darin, einfach auszusteigen, wenn der Benutzer bereits vorhanden ist (oder den vorhandenen Benutzerdatensatz zu aktualisieren).
Will
6
Zumindest auf Django 1.11. Die Reihenfolge der Argumente ist ('Benutzername', 'E-Mail', 'Pass'), nicht ('E-Mail', 'Benutzername', 'Pass'). Siehe: docs.djangoproject.com/de/1.11/ref/contrib/auth/…
np8
3
from django.contrib.auth.models import Userfunktioniert nicht mehr. Verwenden Sie diese: from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', '[email protected]', 'my secure password')
dcalde
48

Ich habe selbst nach einer Antwort gesucht. Ich habe beschlossen, einen Django-Befehl zu erstellen, der den Basisbefehl createsuperuser( GitHub ) erweitert:

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

Anwendungsbeispiel:

./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email '[email protected]'

Dies hat den Vorteil, dass die Standardbefehlsverwendung weiterhin unterstützt wird und gleichzeitig eine nicht interaktive Verwendung zur Angabe eines Kennworts möglich ist.

Adam Charnock
quelle
4
Dies sollte die am besten bewertete (und akzeptierte) Antwort sein.
Bruno Desthuilliers
Ich wünschte, die Standardeinstellung createsuperuserhätte auch dieses --passwordFeld
Shadi
1
Sie könnten ein Beispiel für die Verwendung hinzufügen:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email '[email protected]'
Shadi
2
Wie wird createsuperuser2dieser Klasse zugeordnet, Funktion
Srinath Ganesh
2
@SrinathGanesh werfen Sie einen Blick auf docs.djangoproject.com/de/1.8/howto/custom-management-commands. Sie müssen die Python-Datei benennen createsuperuser2.pyund über den obigen Link in die definierte Verzeichnisstruktur einfügen .
ElectRocnic
41

Ich benutze './manage.py shell -c':

./manage.py shell -c "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'adminpass')"

Dies verwendet kein zusätzliches Echo. Dies hat den Vorteil, dass Sie es zur Ausführung an einen Docker-Container übergeben können. Ohne die Notwendigkeit, sh -c "..." zu verwenden , bringt Sie das Zitat dazu, der Hölle zu entkommen.

Und denken Sie daran, dass zuerst der Benutzername als die E-Mail kommt.

Wenn Sie ein benutzerdefiniertes Benutzermodell haben, müssen Sie dieses importieren und nicht auth.models.User

yvess
quelle
1
Hat für mich gearbeitet. Vielen Dank!
TimH - Codidact
Scheint nicht für mich zu funktionieren, ich AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
sehe
Wenn Sie ein benutzerdefiniertes Benutzermodell haben, wie users.User Sie es importieren müssen und nicht vonauth.User
yvess
29

Ich würde vorschlagen, eine Datenmigration auszuführen . Wenn also Migrationen auf das Projekt angewendet werden, wird im Rahmen der Migrationen ein Superuser erstellt. Der Benutzername und das Passwort können als Umgebungsvariablen eingerichtet werden. Dies ist auch nützlich, wenn Sie eine App in einem Container ausführen (siehe diesen Thread als Beispiel).

Ihre Datenmigration würde dann folgendermaßen aussehen:

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),
    ]

Hoffentlich hilft das!

BEARBEITEN : Einige werfen möglicherweise die Frage auf, wie diese Umgebungsvariablen festgelegt und Django auf sie aufmerksam gemacht werden können. Es gibt viele Möglichkeiten und es wurde in anderen SO-Posts beantwortet, aber nur als schneller Zeiger ist das Erstellen einer .envDatei eine gute Idee. Sie können dann das Paket python-dotenv verwenden. Wenn Sie jedoch eine virtuelle Umgebung mit pipenv eingerichtet haben, werden die envvars in Ihrer .envDatei automatisch festgelegt . Ebenso kann das Ausführen Ihrer App über Docker-Compose Ihre .envDatei einlesen .

Hendrik F.
quelle
1
TIPP: Bitte beachten Sie diesen Ansatz . Dies ist eine qualitativ hochwertige Antwort: Sie nutzt natürlich die integrierten Funktionen von Django, um die Frage zu beantworten, anstatt Ad-hoc-Python-Skripte zu wiederholen. Außerdem wird das größte Problem der akzeptierten Antwort angesprochen (eine Migration wird bei einer Bereitstellung nur einmal angewendet , so dass der Benutzer nur einmal erstellt wird). Es funktioniert wunderbar in einem Containerkontext.
Ad N
Dies scheint eine gute Antwort zu sein. Ich weiß immer noch nicht, wo in das Projekt dieser Code passt?
Pablo Ruiz Ruiz
Es sollte sich in Ihrem Migrationsordner befinden, z. B. root/⁨mysite⁩/myapp⁩/⁨migrations⁩- wenn Sie die Dokumente lesen, wird erläutert, wie Sie eine leere Migration erstellen und diese ändern könnenpython manage.py makemigrations --empty yourappname
Hendrik F
Warum brauchst du den DJANGO_DB_NAME? es wird nie benutzt.
Thoroc
Sie sollten Folgendes hinzufügen, um die .env-Variablen in die settings.pyDatei zu laden :python # loading .env from dotenv import load_dotenv from pathlib import Path env_path = Path('.', '.env') load_dotenv(dotenv_path=env_path)
thoroc
21

Ab Django 3.0 können Sie Standard verwenden createsuperuser --noinputBefehl und stellen Sie alle erforderlichen Felder (einschließlich Passwort) als Umgebungsvariablen DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAILzum Beispiel. --noinputFlag ist erforderlich.

Dies stammt aus den Originaldokumenten: https://docs.djangoproject.com/de/3.0/ref/django-admin/#django-admin-createsuperuser

und ich habe gerade überprüft - es funktioniert. Jetzt können Sie diese Umgebungsvariablen einfach exportieren und createsuperuserzu Ihren Skripten und Pipelines hinzufügen .

Alexey Trofimov
quelle
14

Sie können ein einfaches Python-Skript schreiben, um die Automatisierung der Superuser-Erstellung zu übernehmen. Das UserModell ist nur ein normales Django-Modell. Sie folgen also dem normalen Prozess des Schreibens eines eigenständigen Django-Skripts. 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()

Sie können auch createsuperusereinige Optionen übergeben, nämlich --noinputund --username, mit denen Sie automatisch neue Superuser erstellen können. Diese können sich jedoch erst anmelden, wenn Sie ein Kennwort für sie festgelegt haben.

Zeekay
quelle
2
Ok für cretesuperuser, aber wie kann man dann das Passwort einstellen? Ich würde das gerne in einem Bash-Skript machen ...
Caneta
10

Derzeit am häufigsten gewählte Antwort:

  • Löscht den Benutzer, falls vorhanden, und wie von @Groady in den Kommentaren angegeben, besteht die Gefahr, dass Sie alle zugehörigen Datensätze über eine Kaskadenlöschung unbeabsichtigt löschen.
  • Überprüft die Filterung der Superuser-Existenz nach E-Mails. Wenn also zwei Superuser dieselbe E-Mail haben, weiß Gott, welche sie löscht.
  • Das Aktualisieren der Skriptparameter Benutzername, Kennwort und E-Mail ist umständlich.
  • Protokolliert nicht, was es getan hat.

Eine verbesserte Version wäre:

USER="admin"
PASS="super_password"
MAIL="[email protected]"
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
David Darias
quelle
2
Viel sauberer (besser) als die akzeptierte Antwort. Sie könnten auch verwendet haben : if not User.objects.filter(username = username).exists(),
Philippe Fanaro
5
DJANGO_SUPERUSER_USERNAME=testuser \
DJANGO_SUPERUSER_PASSWORD=testpass \
python manage.py createsuperuser --noinput

Dokumentation für den Befehl createuser

Rafal Enden
quelle
Dies ist die einfachste Lösung. Sie können die noinputFlagge jedoch mit anderen Parametern überschreiben :DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email [email protected] --noinput
dannydedog
1

Ich habe Tk421 one liner verwendet, aber eine Fehlermeldung erhalten als: 1) Ich glaube, ich verwende eine spätere Version von Django (1.10) Manager isn't available; 'auth.User' has been swapped for 'users.User'2) Die Reihenfolge der Parameter für create_superuser war falsch.

Also habe ich es ersetzt durch:

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

und was mich genauso freut, ist, dass es auch bei einem Heroku-Einsatz funktioniert:

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

Dies wird immer wieder gut funktionieren. Ich benutze es zu Beginn eines Projekts, also mach dir keine Sorgen über die schrecklichen kaskadierten Löschungen, die später auftreten könnten.

Ich habe nach einigen Problemen mit dem Ausführen von local () aus Fabric erneut besucht. Was zu passieren schien, war, dass das Pfeifensymbol bedeutet, dass es eher lokal als auf Heroku interpretiert wurde. Um dies zu sortieren, habe ich den Befehl in Anführungszeichen gesetzt. Dann mussten dreifache doppelte Anführungszeichen für die Python-Zeichenfolgen in den einfachen Anführungszeichen des gesamten Python-Befehls verwendet werden.

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"
hum3
quelle
1

Eine Lösung, die auf dem oben beschriebenen Ansatz von Adam Charnock basiert, ist jetzt als Python-Paket verfügbar. Es dauert drei Schritte:

  1. Installieren: pip install django-createsuperuserwithpassword

  2. Aktivieren Sie: INSTALLED_APPS += ("django_createsuperuserwithpassword", )

  3. Anwenden:

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

Das ist es.

Sebastian
quelle
0

Dieses kleine Python-Skript kann einen normalen Benutzer oder einen Superuser erstellen

#!/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 & --password sind nicht obligatorisch.

Wenn --superuser nicht definiert ist, wird ein normaler Benutzer erstellt. Wenn --password nicht definiert ist, wird ein zufälliges Passwort generiert

    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 
Thibault Richard
quelle
0

Dies ist, was ich für Heroku post_deploy und eine vordefinierte app.json- Variable zusammengeschustert habe:

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

Damit können Sie eine einzelne env-Variable haben:

CREATE_SUPER_USER=admin:admin@example.com:password

Ich mag die Shell- Option --command , bin mir aber nicht sicher, wie das Newline-Zeichen im Befehlsskript abgerufen wird. Ohne den Zeilenumbruch führt der ifAusdruck zu einem Syntaxfehler.

Janusz Skonieczny
quelle
0

Gehen Sie zur Eingabeaufforderung und geben Sie Folgendes ein:

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

Wenn die Migration nicht ausgeführt wurde, gehen Sie zum Django-Anwendungsordner und führen Sie Folgendes aus

  1. python manage.py migrieren
  2. python manage.py erstellt einen Superuser

dann Bingo.

Arif Khan
quelle
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',
                           '[email protected]', 'admin1')"
Raja R.
quelle
0

Mit shell_plus ist es tatsächlich viel einfacher

echo "User.objects.create_superuser('[email protected]', 'test')" | python manage.py shell_plus

Wie bereits erwähnt, können Sie mit Django 3.0 die Anmeldeinformationen über Umgebungsvariablen übergeben. Dieser Ansatz ist jedoch viel flexibler, da Sie damit jede andere kompliziertere Aufgabe ausführen können, z. B. das Entfernen aller Testbenutzer usw.

Pithikos
quelle