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

129

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

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

Bogdan
источник
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
Tk421
источник
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

yvess
источник
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, которые позволят вам автоматически создавать новых суперпользователей, но они не смогут войти в систему, пока вы не установите для них пароль.

zeekay
источник
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"
hum3
источник
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

un33k
источник
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 вы можете передавать учетные данные через переменные среды. Однако этот подход гораздо более гибкий, поскольку он позволяет выполнять любую другую более сложную задачу, например, удалить всех пользователей тестов и т. Д.

Pithikos
источник