Làm thế nào để tự động tạo người dùng trên django?


128

Tôi muốn tự động chạy manage.py createsuperusertrên djangonhưng nó seams rằng không có cách nào thiết lập một mật khẩu mặc định.

Làm thế nào tôi có thể nhận được điều này? Nó phải độc lập trên cơ sở dữ liệu django.


1
bạn đã xem xét việc chỉ lưu siêu người dùng đã tạo của mình một vật cố định và tải nó bằng cách sử dụng management.py chưa?
turbotux 27/02/17

1
@turbotux Hendrik F answer có cách tiếp cận tương tự như những gì bạn đề xuất, với khả năng được bổ sung để đọc các giá trị (đăng nhập, mật khẩu ...) từ env vars (hoặc hệ thống tệp, ...). Tôi thực sự khuyên bạn nên đi theo hướng này thay vì các tập lệnh python đặc biệt, có vấn đề khi bạn khởi động lại ứng dụng.
Quảng cáo N

Câu trả lời:


145

Nếu bạn tham chiếu trực tiếp tới Người dùng , mã của bạn sẽ không hoạt động trong các dự án mà cài đặt AUTH_USER_MODEL đã được thay đổi thành mô hình người dùng khác. Một cách chung chung hơn để tạo người dùng sẽ là:

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

CÂU TRẢ LỜI GỐC

Đây là một phiên bản đơn giản của tập lệnh để tạo siêu người dùng:

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

2
siêu hữu ích khi cố gắng tạo siêu người dùng trong heroku và mạng của bạn chặn cổng 5000
Vic

4
Tôi sẽ xóa siêu người dùng hiện có, vì vậy điều này hợp lệ cho mọi bản dựng: 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
Cá nhân tôi không nghĩ rằng việc xóa người dùng trên mỗi bản dựng là một ý kiến ​​hay. Bạn có nguy cơ vô tình xóa bất kỳ bản ghi liên quan nào thông qua xóa theo tầng. Một tùy chọn an toàn hơn là chỉ cần cứu trợ nếu người dùng đã tồn tại (hoặc cập nhật hồ sơ Người dùng hiện có).
Will

6
Ít nhất là trên Django 1.11. thứ tự của các đối số là ('tên người dùng', 'email', 'pass'), không phải ('email', 'tên người dùng', 'pass'). Xem: docs.djangoproject.com/en/1.11/ref/contrib/auth/…
np8

3
from django.contrib.auth.models import Usercông việc ngắn hạn. Sử dụng cái này: 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

Tôi đã tự tìm kiếm câu trả lời cho điều này. Tôi quyết định tạo một lệnh Django mở rộng createsuperuserlệnh cơ sở ( 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()

Ví dụ sử dụng:

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

Điều này có lợi thế là vẫn hỗ trợ sử dụng lệnh mặc định, đồng thời cho phép sử dụng không tương tác để chỉ định mật khẩu.


4
Đây sẽ là câu trả lời được ủng hộ nhiều nhất (và được chấp nhận).
bruno desthuilliers

Tôi ước gì mặc định createsuperusercũng có --passwordtrường này
shadi

1
Bạn có thể thêm một ví dụ sử dụng:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'
shadi

2
làm thế nào được createsuperuser2ánh xạ tới lớp, hàm này
Srinath Ganesh

2
@SrinathGanesh hãy xem docs.djangoproject.com/en/1.8/howto/custom-management-commands Bạn cần đặt tên cho tệp python createsuperuser2.pyvà đặt nó vào cấu trúc thư mục đã xác định từ liên kết ở trên.
ElectRocnic

43

Tôi sử dụng './manage.py shell -c':

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

Điều này không sử dụng thêm tiếng vọng, điều này có lợi ích là bạn có thể chuyển nó đến vùng chứa docker để thực thi. Không cần phải sử dụng sh -c "..." mà bạn sẽ được trích dẫn thoát khỏi địa ngục.

Và hãy nhớ rằng tên người dùng đi kèm đầu tiên , hơn là email.

Nếu bạn có một mô hình người dùng tùy chỉnh, bạn cần nhập mô hình đó và không auth.models.User


1
Đã làm cho tôi. Cảm ơn!
TimH - Codidact

Có vẻ như không hiệu quả với tôi, tôi đang thấy:AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
Brodan

khi bạn có một mô hình người dùng tùy chỉnh như users.User bạn cần nhập từ đó chứ không phải từauth.User
yvess 26/02 '19

30

Tôi khuyên bạn nên chạy Di chuyển dữ liệu , vì vậy khi các di chuyển được áp dụng cho dự án, một superuser sẽ được tạo như một phần của quá trình di chuyển. Tên người dùng và mật khẩu có thể được thiết lập làm biến môi trường. Điều này cũng hữu ích khi chạy ứng dụng trong vùng chứa (xem chuỗi này làm ví dụ)

Di chuyển dữ liệu của bạn sau đó sẽ trông giống như sau:

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

Hy vọng rằng sẽ giúp!

CHỈNH SỬA : Một số người có thể đặt ra câu hỏi làm thế nào để đặt các biến môi trường này và làm cho Django biết về chúng. Có rất nhiều cách và nó đã được trả lời trong các bài đăng SO khác, nhưng chỉ là một con trỏ nhanh, tạo một .envtệp là một ý tưởng hay. Sau đó, bạn có thể sử dụng gói python-dotenv , nhưng nếu bạn đã thiết lập một môi trường ảo với pipenv, nó sẽ tự động đặt các envvars trong .envtệp của bạn . Tương tự như vậy, việc chạy ứng dụng của bạn thông qua docker-soạn có thể đọc trong .envtệp của bạn .


1
MẸO: Hãy xem xét cách tiếp cận này . Đây là một câu trả lời chất lượng cao: nó tự nhiên tận dụng các chức năng tích hợp sẵn của Django để trả lời câu hỏi thay vì lặp lại các tập lệnh python đặc biệt, cộng với nó tự nhiên giải quyết vấn đề lớn nhất của câu trả lời được chấp nhận (một lần di chuyển chỉ được áp dụng một lần khi triển khai , vì vậy người dùng chỉ được tạo một lần). Nó hoạt động tuyệt vời trong bối cảnh vùng chứa.
Quảng cáo N

Đây có vẻ là một câu trả lời tuyệt vời. Tôi vẫn không biết đoạn mã này nằm ở đâu trong dự án?
Pablo Ruiz Ruiz

Nó phải ở trong cuộc di cư của bạn thư mục, ví dụ như root/⁨mysite⁩/myapp⁩/⁨migrations⁩- nếu đọc các tài liệu của bạn, nó giải thích làm thế nào bạn có thể tạo một di cư trống và sửa đổipython manage.py makemigrations --empty yourappname
Hendrik F

Tại sao bạn cần DJANGO_DB_NAME? nó không bao giờ được sử dụng.
thoroc

Bạn nên đề cập đến việc thêm phần sau để tải các vars .env vào settings.pytệp:python # loading .env from dotenv import load_dotenv from pathlib import Path env_path = Path('.', '.env') load_dotenv(dotenv_path=env_path)
thoroc

23

Tính đến Django 3.0 bạn có thể sử dụng mặc định createsuperuser --noinputlệnh và đặt tất cả các trường bắt buộc (bao gồm cả mật khẩu) như biến môi trường DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAILví dụ. --noinputcờ là bắt buộc.

Điều này đến từ tài liệu gốc: https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-createsuperuser

và tôi vừa kiểm tra - nó hoạt động. Giờ đây, bạn có thể dễ dàng xuất các giao diện môi trường đó và thêm createsuperuservào các tập lệnh và đường dẫn của mình.


14

Bạn có thể viết một tập lệnh python đơn giản để xử lý quá trình tự động tạo siêu người dùng. Các Usermô hình chỉ là một mô hình Django bình thường, vì vậy bạn muốn theo dõi quá trình bình thường của việc viết một kịch bản Django độc lập. Ví dụ:

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

Bạn cũng có thể vượt qua createsuperusermột số tùy chọn, cụ thể là --noinput--usernamecho phép bạn tự động tạo siêu người dùng mới, nhưng họ sẽ không thể đăng nhập cho đến khi bạn đặt mật khẩu cho họ.


2
Ok cho cretesuperuser, nhưng làm thế nào để đặt mật khẩu sau đó? Tôi muốn làm điều đó trong một kịch bản bash ...
caneta

10

Câu trả lời được bình chọn nhiều nhất hiện tại:

  • Xóa người dùng nếu nó tồn tại và như được @Groady lưu ý trong phần nhận xét, bạn có nguy cơ vô tình xóa bất kỳ bản ghi nào liên quan thông qua xóa theo tầng.
  • Kiểm tra việc lọc sự tồn tại của superuser qua thư để nếu hai superuser có cùng thư thần sẽ biết nó sẽ xóa cái nào.
  • Việc cập nhật các tham số tập lệnh: tên người dùng, mật khẩu và thư là rườm rà.
  • Không ghi lại những gì nó đã làm.

Một phiên bản cải tiến sẽ là:

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
Rõ ràng hơn nhiều (tốt hơn) so với câu trả lời được chấp nhận. Bạn cũng có thể sử dụng: if not User.objects.filter(username = username).exists(),
Philippe Fanaro

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

Tài liệu cho lệnh createuser


Đây là giải pháp dễ dàng nhất. Nhưng bạn có thể ghi đè noinputcờ bằng các tham số khác:DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email admin@email.com --noinput
dannydedog

1

Tôi đã sử dụng Tk421 một lớp lót nhưng nhận được thông báo lỗi như: 1) Tôi nghĩ rằng tôi đang sử dụng phiên bản mới hơn của Django (1.10) Manager isn't available; 'auth.User' has been swapped for 'users.User'2) thứ tự của các tham số tạo_superuser bị sai.

Vì vậy, tôi đã thay thế nó bằng:

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

và điều tôi thực sự hài lòng là nó cũng hoạt động trên việc triển khai 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

Điều này sẽ hoạt động tốt nhiều lần. Tôi đang sử dụng nó khi bắt đầu dự án, vì vậy đừng lo lắng về những lần xóa theo tầng khủng khiếp có thể xảy ra sau này.

Tôi đã truy cập lại sau một số rắc rối với việc chạy điều này bên trong local () từ vải. điều dường như đang xảy ra là biểu tượng cái ống có nghĩa là nó được diễn giải cục bộ hơn là trên heroku. Để sắp xếp điều này, tôi gói lệnh trong dấu ngoặc kép. Sau đó, phải sử dụng ba dấu ngoặc kép cho các chuỗi python bên trong dấu nháy đơn của toàn bộ lệnh 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

Một giải pháp dựa trên cách tiếp cận của Adam Charnock ở trên đã có sẵn dưới dạng một gói Python. Phải thực hiện ba bước:

  1. Tải về: pip install django-createsuperuserwithpassword

  2. Kích hoạt: INSTALLED_APPS += ("django_createsuperuserwithpassword", )

  3. Ứng dụng:

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

Đó là nó.



0

Tập lệnh python nhỏ này có thể tạo ra một người dùng bình thường hoặc một siêu người dùng

#!/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 là không bắt buộc.

Nếu --superuser không được xác định, người dùng bình thường sẽ được tạo Nếu - mật khẩu không được xác định, một mật khẩu ngẫu nhiên sẽ được tạo

    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

Đây là những gì tôi đã tập hợp cùng nhau cho Heroku post_deploy và một biến app.json được xác định trước :

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

Với điều này, bạn có thể có một biến env duy nhất:

CREATE_SUPER_USER=admin:admin@example.com:password

Tôi thích tùy chọn shell --command , nhưng không chắc cách lấy ký tự dòng mới trong tập lệnh lệnh. Nếu không có dòng mới, ifbiểu thức dẫn đến lỗi cú pháp.


0

Đi tới dấu nhắc lệnh và nhập:

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

nếu không thực hiện quá trình di chuyển thì hãy chuyển đến thư mục ứng dụng django và thực hiện theo sau

  1. python management.py di chuyển
  2. python management.py createuperuser

rồi chơi lô tô.


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

Với shell_plus, nó thực sự dễ dàng hơn nhiều

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

Như những người khác đã đề cập, với Django 3.0, bạn có thể chuyển thông tin đăng nhập thông qua các biến môi trường. Tuy nhiên, cách tiếp cận này linh hoạt hơn nhiều vì nó cho phép bạn thực hiện bất kỳ tác vụ nào khác phức tạp hơn như xóa tất cả người dùng thử nghiệm, v.v.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.