Bagaimana cara mengotomatiskan createuperuser di django?

128

Saya ingin auto run manage.py createsuperuserpada djangotetapi jahitan bahwa tidak ada cara pengaturan password default.

Bagaimana saya bisa mendapatkan ini? Ini harus independen pada database django.

bogdan
sumber
1
Sudahkah Anda melihat ke dalam hanya menyimpan perlengkapan superuser yang Anda buat dan memuatnya menggunakan manage.py?
turbotux
1
@turbotux Hendrik F jawaban mengambil pendekatan yang mirip dengan apa yang Anda sarankan, dengan kemampuan tambahan untuk membaca nilai (login, password ...) dari env vars (atau filesystem, ...). Saya sangat menyarankan untuk pergi ke arah ini daripada skrip python ad-hoc, yang memiliki masalah saat Anda memulai ulang aplikasi.
Ad N

Jawaban:

145

Jika Anda mereferensikan Pengguna secara langsung, kode Anda tidak akan berfungsi dalam proyek yang setelan AUTH_USER_MODEL telah diubah ke model pengguna lain. Cara yang lebih umum untuk membuat pengguna adalah:

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

JAWABAN ASLI

Di sini ada versi sederhana dari script untuk membuat superuser:

echo "from django.contrib.auth.models import User; User.objects.create_superuser('admin', '[email protected]', 'pass')" | python manage.py shell
Tk421
sumber
2
sangat berguna saat mencoba membuat pengguna super di heroku dan port blok jaringan Anda 5000
Vic
4
Saya akan menghapus superuser yang ada, jadi ini berlaku untuk setiap 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
Secara pribadi, menurut saya menghapus pengguna di setiap build adalah ide yang bagus. Anda berisiko secara tidak sengaja menghapus rekaman terkait melalui penghapusan bertingkat. Opsi yang lebih aman adalah dengan melakukan bail-out jika pengguna sudah ada (atau memperbarui catatan Pengguna yang ada).
Akankah
6
Setidaknya di Django 1.11. urutan argumennya adalah ('username', 'email', 'pass'), bukan ('email', 'username', 'pass'). Lihat: docs.djangoproject.com/en/1.11/ref/contrib/auth/…
np8
3
from django.contrib.auth.models import Usertidak lagi berfungsi. Gunakan ini: from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', '[email protected]', 'my secure password')
dcalde
49

Saya sedang mencari jawaban untuk ini sendiri. Saya memutuskan untuk membuat perintah Django yang memperluas createsuperuserperintah dasar ( 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()

Contoh penggunaan:

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

Keuntungannya adalah tetap mendukung penggunaan perintah default, sementara juga memungkinkan penggunaan non-interaktif untuk menentukan sandi.

Adam Charnock
sumber
4
Ini harus menjadi jawaban yang paling disukai (dan diterima).
bruno desthuilliers
Saya berharap default createsuperusermemiliki --passwordbidang ini juga
shadi
1
Anda dapat menambahkan contoh penggunaan:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email '[email protected]'
shadi
2
bagaimana createsuperuser2dipetakan ke kelas ini, fungsi
Srinath Ganesh
2
@SrinathGanesh lihat di docs.djangoproject.com/en/1.8/howto/custom-management-commands Anda perlu memberi nama file python createsuperuser2.pydan menempatkannya ke dalam struktur direktori yang ditentukan dari tautan di atas.
ElectRocnic
43

Saya menggunakan './manage.py shell -c':

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

Ini tidak menggunakan echo ekstra, ini memiliki keuntungan bahwa Anda dapat meneruskannya ke kontainer buruh pelabuhan untuk dieksekusi. Tanpa perlu menggunakan sh -c "..." yang membuat Anda dikutip dari neraka.

Dan ingat bahwa yang pertama datang adalah nama pengguna, daripada email.

Jika Anda memiliki model pengguna khusus, Anda perlu mengimpornya dan tidak auth.models.User

yvess
sumber
1
Bekerja untuk saya. Terima kasih!
TimH - Codidact
Tampaknya tidak berhasil untuk saya, saya melihat:AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
Brodan
bila Anda memiliki model pengguna ubahsuaian seperti users.User Anda perlu mengimpor dari model itu dan bukan dariauth.User
yvess
30

Saya akan menyarankan menjalankan Migrasi Data , jadi ketika migrasi diterapkan ke proyek, pengguna super dibuat sebagai bagian dari migrasi. Nama pengguna dan kata sandi dapat diatur sebagai variabel lingkungan. Ini juga berguna saat menjalankan aplikasi dalam wadah (lihat utas ini sebagai contoh)

Migrasi data Anda akan terlihat seperti ini:

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

Semoga membantu!

EDIT : Beberapa mungkin memunculkan pertanyaan bagaimana menyetel variabel lingkungan ini dan membuat Django menyadarinya. Ada banyak cara dan sudah terjawab di posting SO lainnya, tetapi hanya sebagai penunjuk cepat, membuat .envfile adalah ide yang bagus. Anda kemudian dapat menggunakan paket python-dotenv , tetapi jika Anda telah menyiapkan lingkungan virtual dengan pipenv, itu akan secara otomatis mengatur envars di .envfile Anda . Demikian pula, menjalankan aplikasi Anda melalui docker-compose dapat membaca .envfile Anda .

Hendrik F
sumber
1
TIP: Harap pertimbangkan pendekatan ini . Ini adalah jawaban berkualitas tinggi: ini secara alami memanfaatkan fungsionalitas bawaan Django untuk menjawab pertanyaan alih-alih menggemakan skrip python ad-hoc, ditambah secara alami menjawab masalah terbesar dari jawaban yang diterima (migrasi diterapkan hanya sekali pada penerapan , jadi pengguna hanya dibuat sekali). Ia bekerja dengan baik dalam konteks wadah.
Ad N
Sepertinya ini jawaban yang bagus. Saya masih tidak tahu di bagian mana dalam proyek ini potongan kode ini cocok?
Pablo Ruiz Ruiz
Ini harus ada di folder migrasi Anda, misalnya root/⁨mysite⁩/myapp⁩/⁨migrations⁩- jika Anda membaca dokumen, ini menjelaskan bagaimana Anda dapat membuat migrasi kosong dan mengubahnyapython manage.py makemigrations --empty yourappname
Hendrik F
Mengapa Anda membutuhkan DJANGO_DB_NAME? itu tidak pernah digunakan.
thoroc
Anda harus menyebutkan untuk menambahkan yang berikut untuk memuat .env vars ke 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

Pada Django 3.0 dapat Anda gunakan standar createsuperuser --noinputperintah dan mengatur semua bidang yang diperlukan (termasuk password) sebagai variabel lingkungan DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAILmisalnya. --noinputbendera diperlukan.

Ini berasal dari dokumen asli: https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-createsuperuser

dan saya baru saja memeriksanya - berhasil. Sekarang Anda dapat dengan mudah mengekspor variabel lingkungan tersebut dan menambahkannya createsuperuserke skrip dan pipeline Anda.

Alexey Trofimov
sumber
14

Anda dapat menulis skrip python sederhana untuk menangani otomatisasi pembuatan superuser. The UserModel hanya model Django normal, sehingga Anda akan mengikuti proses normal menulis Django naskah berdiri sendiri. 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()

Anda juga dapat memberikan createsuperuserbeberapa opsi, yaitu --noinputdan --username, yang memungkinkan Anda membuat superuser baru secara otomatis, tetapi mereka tidak akan dapat masuk hingga Anda menyetel kata sandi untuk mereka.

zeekay
sumber
2
Ok untuk cretesuperuser, tapi bagaimana cara mengatur kata sandinya? Saya ingin melakukannya di dalam skrip bash ...
caneta
10

Jawaban yang paling banyak dipilih saat ini:

  • Menghapus pengguna jika ada dan seperti yang dicatat oleh @Groady dalam komentar, Anda berisiko secara tidak sengaja menghapus semua catatan terkait melalui penghapusan bertingkat.
  • Memeriksa pemfilteran keberadaan pengguna super melalui surat jadi jika dua pengguna super memiliki surat yang sama, tuhan tahu mana yang dihapusnya.
  • Sulit untuk memperbarui parameter skrip: nama pengguna, kata sandi, dan surat.
  • Tidak mencatat apa yang dilakukannya.

Versi yang ditingkatkan adalah:

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
sumber
2
Jauh lebih bersih (lebih baik) daripada jawaban yang diterima. Anda juga bisa menggunakan: if not User.objects.filter(username = username).exists(),
Philippe Fanaro
5
DJANGO_SUPERUSER_USERNAME=testuser \
DJANGO_SUPERUSER_PASSWORD=testpass \
python manage.py createsuperuser --noinput

Dokumentasi untuk perintah createuser

Rafal Enden
sumber
Ini adalah solusi termudah. Tetapi Anda dapat menimpa noinputbendera dengan parameter lain:DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email [email protected] --noinput
dannydedog
1

Saya menggunakan Tk421 satu liner tetapi mendapat pesan kesalahan sebagai: 1) Saya pikir saya menggunakan versi Django (1.10) Manager isn't available; 'auth.User' has been swapped for 'users.User'2) urutan parameter untuk create_superuser salah.

Jadi saya menggantinya dengan:

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

dan yang sangat saya sukai adalah ini berfungsi pada penerapan heroku juga:

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

Ini akan bekerja dengan baik berulang kali. Saya menggunakannya di awal proyek jadi jangan khawatir tentang penghapusan bertingkat mengerikan yang mungkin terjadi nanti.

Saya telah mengunjungi kembali setelah beberapa masalah dengan menjalankan ini di dalam lokal () dari kain. apa yang tampaknya terjadi adalah bahwa simbol pipa berarti ditafsirkan secara lokal daripada di heroku. Untuk mengurutkan ini, saya membungkus perintah dalam tanda kutip. Kemudian harus menggunakan tanda kutip ganda rangkap tiga untuk string python di dalam tanda kutip tunggal dari seluruh perintah 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"
hum3
sumber
1

Sebuah solusi berdasarkan Adam Charnock pendekatan 's atas tersedia sebagai paket Python sekarang. Dibutuhkan tiga langkah:

  1. Install: pip install django-createsuperuserwithpassword

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

  3. Menerapkan:

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

Itu dia.

Sebastian
sumber
0

Skrip python kecil ini bisa membuat pengguna biasa atau superuser

#!/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 tidak wajib diisi.

Jika --superuser tidak ditentukan, pengguna biasa akan dibuat Jika --password tidak ditentukan, kata sandi acak akan dibuat

    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
sumber
0

Inilah yang saya buat untuk Heroku post_deploy dan variabel app.json yang telah ditentukan :

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

Dengan ini, Anda dapat memiliki satu variabel env:

CREATE_SUPER_USER=admin:admin@example.com:password

Saya suka opsi shell --command , tetapi tidak yakin bagaimana mendapatkan karakter baris baru dalam skrip perintah. Tanpa baris baru, ifekspresi menghasilkan kesalahan sintaksis.

Janusz Skonieczny
sumber
0

Pergi ke command prompt dan ketik:

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

jika tidak dijalankan migrasi maka pergi ke folder aplikasi django dan jalankan berikut ini

  1. python manage.py migrate
  2. python manage.py createuperuser

lalu bingo.

Arif Khan
sumber
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
sumber
0

Dengan shell_plus sebenarnya jauh lebih mudah

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

Seperti yang disebutkan orang lain, dengan Django 3.0 Anda dapat meneruskan kredensial melalui variabel lingkungan. Namun pendekatan ini jauh lebih fleksibel karena memungkinkan Anda melakukan tugas lain yang lebih rumit seperti menghapus semua pengguna pengujian, dll.

Pithikos
sumber