Не могу создать суперпользователя Django

Решил расширить модель User, используя UserManager. Все настроил, сделал все миграции. Форма регистрации заработала, но: py manage.py createsuperuser выдает ошибку:

TypeError: create_superuser() missing 1 required positional argument: 'username'

Я написал менеджер по примерам из интернета, но на проблему это никак не повлияло.

models.py

from django.db import models
from django.contrib.auth.models import AbstractUser, UserManager

class Manager(UserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Пользователь должен иметь email')
        user=self.model(email=email,)
        user.save(using=self._db)
        return user
    def create_superuser(self, email, password=None):
        user=self.model(email=email,)
        user.username=""
        user.is_staff=True
        user.is_superuser=True
        user.set_password(password)
        user.save(using=self._db)
        return user

class User(AbstractUser):
    specialization = models.CharField(max_length=250, verbose_name="Направление")
    username = None
    email = models.EmailField('Email', unique=True)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

def __str__(self):
    return self.specialization, self.email

Версия Django 3.1.2

Вроде всё сделал правильно, но работать оно всё равно не хочет. Не могу понять, что я упустил. Помогите прошу.


Ответы (1 шт):

Автор решения: Sergey S.

Вы объявили, но не указали какой менеджер использовать. добавьте в модель objects = Manager(), а также не передаете поле username в функцию create_superuser(), исправьте на create_superuser(self, username, email, password)

Не совсем понимаю зачем вы пытаетесь сделать поле username пустой строкой, при этом в вашей модели username даже не является полем.

Если вы хотите реализовать пользовательскую модель без поля username сделайте это примерно так:

models.py

from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.utils.translation import ugettext_lazy as _

from .managers import UserManager


class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField('email', unique=True)
    first_name = models.CharField('имя', max_length=150, blank=False)
    last_name = models.CharField('фамилия', max_length=150, blank=False)

    is_active = models.BooleanField('активный пользователь', default=False)

    date_joined = models.DateTimeField(_('date joined'), auto_now_add=True)
    last_login = models.DateTimeField(_('last login'), blank=True, null=True)
    updated = models.DateTimeField('обновлено', auto_now=True)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['first_name', 'last_name']

    class Meta:
        abstract = False

managers.py:

from django.contrib.auth.base_user import BaseUserManager


class UserManager(BaseUserManager):
    use_in_migrations = True

    def _create_user(self, email, password, **extra_fields):
        if not email:
            raise ValueError('Поле email не может быть пустым! ')
        email = self.normalize_email(email)
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_user(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, password, **extra_fields)

    def create_superuser(self, email, password=None, **extra_fields):
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError('Администратор должен иметь is_staff=True.')
        if extra_fields.get('is_superuser') is not True:
            raise ValueError('Администратор должен иметь is_superuser=True.')

        return self._create_user(email, password, **extra_fields)

Также вам необходимо переопределить стандартную команду Django createsuperuser на свою. Создайте папку management, затем в ней папку commands. Не забудьте в каждую из этих папок положить пустой файл __init__.py, так как они должны являться питоновскими пакетами. В папке commands создайте файл createsuperuser.py:

from django.contrib.auth.management.commands import createsuperuser
from django.core.management import CommandError


class Command(createsuperuser.Command):
    help = 'Create a superuser with a password non-interactively'

    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):
        options.setdefault('interactive', False)
        database = options.get('database')
        password = options.get('password')
        email = options.get('email')
        first_name = options.get('first_name')
        last_name = options.get('last_name')

        if not password or not email or not first_name or not middle_name or not last_name or not phone:
            raise CommandError(
                "--email, --password, --first_name and --last_name are required options")

        user_data = {
            'password': password,
            'email': email,
            'first_name': first_name,
            'last_name': last_name,
        }

        self.UserModel._default_manager.db_manager(
            database).create_superuser(**user_data)

        if options.get('verbosity', 0) >= 1:
            self.stdout.write("Superuser created successfully.")

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

→ Ссылка