Как автоматизировать createuperuser на django?


129

Я хочу автоматический запуск manage.py createsuperuserна djangoно швы , что не существует никакого способа установки пароля по умолчанию.

Как я могу это получить? Он должен быть независимым от базы данных django.


1
Вы смотрели, как просто сохранить созданного суперпользователя и загрузить его с помощью manage.py?
turbotux

1
Ответ @turbotux Hendrik F использует подход, аналогичный тому, что вы предлагаете, с добавленной возможностью чтения значений (логин, пароль ...) из env vars (или файловой системы, ...). Я настоятельно рекомендую пойти в этом направлении вместо специальных сценариев python, у которых возникают проблемы при перезапуске приложения.
Объявление N

Ответы:


145

Если вы напрямую ссылаетесь на пользователя , ваш код не будет работать в проектах, где параметр AUTH_USER_MODEL был изменен на другую модель пользователя. Более общий способ создания пользователя:

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

ОРИГИНАЛЬНЫЙ ОТВЕТ

Вот простая версия скрипта для создания суперпользователя:

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

2
супер полезно при попытке создать суперпользователя в heroku и ваша сеть блокирует порт 5000
Вик

4
Я бы удалил существующего суперпользователя, так что это действительно для каждой сборки: 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 01

12
Лично я не думаю, что удаление пользователя в каждой сборке - хорошая идея. Вы рискуете непреднамеренно удалить любые связанные записи с помощью каскадного удаления. Более безопасный вариант - просто выйти из программы, если пользователь уже существует (или обновить существующую запись пользователя).
Will

6
По крайней мере, на Django 1.11. порядок аргументов следующий («имя пользователя», «электронная почта», «пройти»), а не («электронная почта», «имя пользователя», «пройти»). См .: docs.djangoproject.com/en/1.11/ref/contrib/auth/…
np8,

3
from django.contrib.auth.models import Userбольше не работает. Используйте это: 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

Я сам искал на это ответ. Я решил создать команду Django, которая расширяет базовую createsuperuserкоманду ( 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()

Пример использования:

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

Это имеет то преимущество, что по-прежнему поддерживает использование команд по умолчанию, а также позволяет неинтерактивное использование для указания пароля.


4
Это должен быть самый одобренный (и принятый) ответ.
бруно дествильерс

Хотелось бы, чтобы по умолчанию createsuperuserтоже было это --passwordполе
shadi

1
Вы можете добавить пример использования:./manage.py createsuperuser2 --username test1 --password 123321 --noinput --email 'blank@email.com'
shadi

2
как createsuperuser2сопоставляется с этим классом, функция
Шринат Ганеш

2
@SrinathGanesh взгляните на docs.djangoproject.com/en/1.8/howto/custom-management-commands. Вам нужно назвать файл python createsuperuser2.pyи поместить его в определенную структуру каталогов по ссылке выше.
ElectRocnic

43

Я использую './manage.py shell -c':

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

Это не использует дополнительное эхо, это имеет то преимущество, что вы можете передать его в контейнер докера для выполнения. Без необходимости использовать sh -c "...", который вводит вас в кавычки, спасаясь от ада.

И помните, что сначала идет имя пользователя, а не электронная почта.

Если у вас есть собственная модель пользователя, вам нужно импортировать ее, а не auth.models.User


1
Работал у меня. Спасибо!
TimH - Codidact

Похоже, у меня не работает, я вижу:AttributeError: Manager isn't available; 'auth.User' has been swapped for 'users.User'
Бродан

когда у вас есть настраиваемая модель пользователя, например, users.User вам нужно импортировать из auth.User
нее

30

Я бы предложил запустить миграцию данных , поэтому, когда миграции применяются к проекту, суперпользователь создается как часть миграции. Имя пользователя и пароль могут быть установлены как переменные среды. Это также полезно при запуске приложения в контейнере (см. Этот поток в качестве примера)

Тогда ваша миграция данных будет выглядеть так:

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

Надеюсь, это поможет!

РЕДАКТИРОВАТЬ : Некоторые могут поднять вопрос, как установить эти переменные среды и заставить Django знать о них. Есть много способов, и на них ответили в других сообщениях SO, но, как быстрый указатель, создание .envфайла - хорошая идея. Затем вы можете использовать пакет python-dotenv , но если вы настроили виртуальную среду с помощью pipenv, он автоматически установит envvars в вашем .envфайле. Аналогичным образом, запуск вашего приложения через docker-compose может читать в вашем .envфайле.


1
СОВЕТ: рассмотрите этот подход . Это качественный ответ: он, естественно, использует встроенные функции Django для ответа на вопрос вместо повторения специальных сценариев python, плюс он, естественно, решает самую большую проблему принятого ответа (миграция применяется только один раз при развертывании. , поэтому пользователь создается только один раз). Он прекрасно работает в контексте контейнера.
Объявление N

Это кажется отличным ответом. Я до сих пор не знаю, где в проекте подходит этот кусок кода?
Пабло Руис Руис

Он должен быть в вашей папке миграции, например root/⁨mysite⁩/myapp⁩/⁨migrations⁩- если вы читаете документацию, в ней объясняется, как вы можете создать пустую миграцию и изменить ееpython manage.py makemigrations --empty yourappname
Hendrik F

Зачем вам нужен DJANGO_DB_NAME? он никогда не используется.
Thoroc,

Вы должны упомянуть, чтобы добавить следующее для загрузки переменных .env в settings.pyфайл:python # loading .env from dotenv import load_dotenv from pathlib import Path env_path = Path('.', '.env') load_dotenv(dotenv_path=env_path)
thoroc

23

На Django 3.0 вы можете использовать по умолчанию createsuperuser --noinputкоманды и установить все необходимые поля (включая пароль) в качестве переменных окружения DJANGO_SUPERUSER_PASSWORD, DJANGO_SUPERUSER_USERNAME, DJANGO_SUPERUSER_EMAILнапример. --noinputфлаг обязателен.

Это взято из исходных документов: https://docs.djangoproject.com/en/3.0/ref/django-admin/#django-admin-createsuperuser

и я только что проверил - работает. Теперь вы можете легко экспортировать эти переменные среды и добавлять createsuperuserв свои сценарии и конвейеры.


14

Вы можете написать простой скрипт на Python для автоматизации создания суперпользователя. UserМодель просто нормальная модель Django, так что вы хотите следовать нормальному процессу написания автономного Django сценария. Пример:

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

Вы также можете передать createsuperuserнесколько параметров, а именно --noinputи --username, которые позволят вам автоматически создавать новых суперпользователей, но они не смогут войти в систему, пока вы не установите для них пароль.


2
Хорошо cretesuperuser, но как тогда установить пароль? Я хотел бы сделать это внутри сценария bash ...
caneta

10

Текущий ответ с наибольшим количеством голосов:

  • Удаляет пользователя, если он существует, и, как отмечает @Groady в комментариях, вы рискуете непреднамеренно удалить любые связанные записи с помощью каскадного удаления.
  • Проверяет существование суперпользователя, фильтруя по почте, поэтому, если два суперпользователя имеют одинаковую почту, бог знает, какой из них он удаляет.
  • Обновлять параметры скрипта: логин, пароль и почту - громоздко.
  • Не регистрирует, что сделал.

Улучшенная версия будет:

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
Намного чище (лучше), чем принятый ответ. Вы также могли бы использовать: if not User.objects.filter(username = username).exists(),
Филипп Fanaro

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

Документация по команде createuser


Это самое простое решение. Но вы можете перезаписать noinputфлаг другими параметрами:DJANGO_SUPERUSER_PASSWORD=testpass python manage.py createsuperuser --username testuser --email admin@email.com --noinput
dannydedog

1

Я использовал один лайнер Tk421, но получил сообщение об ошибке: 1) Я думаю, что использую более позднюю версию Django (1.10) Manager isn't available; 'auth.User' has been swapped for 'users.User'2) порядок параметров в create_superuser был неправильным.

Поэтому я заменил его на:

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

И что мне действительно понравилось, так это то, что он работает и с развертыванием 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

Это будет хорошо работать повторно. Я использую его в начале проекта, поэтому не беспокойтесь об ужасных каскадных удалениях, которые могут произойти позже.

Я вернулся после некоторых проблем с запуском этого внутри local () из ткани. похоже, что происходит то, что символ трубы означает, что он интерпретировался локально, а не на героку. Чтобы отсортировать это, я заключил команду в кавычки. Затем пришлось использовать тройные двойные кавычки для строк python внутри одинарных кавычек всей команды 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

Решение на основе Адам Чарнок подхода «s выше доступно как пакет Python теперь. Требуется три шага:

  1. Установка: pip install django-createsuperuserwithpassword

  2. Активация: INSTALLED_APPS += ("django_createsuperuserwithpassword", )

  3. Подать заявление:

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

Вот и все.


0

очень просто, прослушайте сигнал post syncdb, прочтите учетные данные суперпользователя из файла конфигурации и примените их.

оформить заказ django-bootup

https://github.com/un33k/django-bootup/blob/master/README


2
ссылка больше не доступна
Tk421

Он находится по адресу: github.com/un33k/django-bootup - но это говорит о том, что оно устарело в пользу github.com/un33k/django-finalware
stephendwolff

0

Этот небольшой скрипт на Python может создать обычного пользователя или суперпользователя.

#!/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 не являются обязательными.

Если --superuser не определен, будет создан обычный пользователь. Если --password не определен, будет сгенерирован случайный пароль.

    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

Это то, что я сколотил для Heroku post_deploy и предопределенной переменной app.json :

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

При этом у вас может быть одна переменная env:

CREATE_SUPER_USER=admin:admin@example.com:password

Мне нравится опция оболочки --command , но я не знаю, как получить символ новой строки в командном скрипте. Без новой строки ifвыражение приводит к синтаксической ошибке.


0

Перейдите в командную строку и введите:

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

если миграция не выполнена, перейдите в папку приложения django и выполните следующие

  1. python manage.py мигрировать
  2. python manage.py создает суперпользователя

затем бинго.


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

С shell_plus на самом деле намного проще

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

Как уже упоминалось, с Django 3.0 вы можете передавать учетные данные через переменные среды. Однако этот подход гораздо более гибкий, поскольку он позволяет выполнять любую другую более сложную задачу, например, удалить всех пользователей тестов и т. Д.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.