【Django】カスタムユーザモデルを使う場合にcreatesuperuserができなくなった時の解決法【初心者】

# createsuperuserができない場合

djangoにてカスタムユーザモデルを作ってCreateSuperUserを実行しようとしてみたところ、
下記エラーが

```
$ python manage.py createsuperuser
Username: username
Password: 
Password (again): 

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    main()
~~ 略 ~~

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

```

email が必要ですよと言われる


作ったmodels.pyを再確認すると、引数で指定したemailが入ってこないから発生していると思われる

```py:models.py
    def _create_user(self, email, username, password, **extra_fields): # 引数にemail
        if not username:
            raise valueError('The given username must be set')
        email = self.normalize_email(email)
        user = self.model(username=username, email=email, **extra_fields)
        user.set_password(password)
        user.save(using=self.db)
        return user

    def create_user(self, email, username, password, **extra_fields): # 引数にemail
        extra_fields.setdefault('is_staff', False)
        extra_fields.setdefault('is_superuser', False)
        return self._create_user(email, username, password, **extra_fields)

    def create_superuser(self, email, username, password, **extra_fields): # 引数にemail
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        if extra_fields.get('is_staff') is not True:
            raise valueError('Superuser must have is_staff=True')
        if extra_fields.get('is_superuser') is not True:
            raise valueError('Superuser must have is_superuser=True')
        return self.create_user(email, username, password, **extra_fields)
```

この時点でのカスタムユーザモデルはこちら

```py:models.py
class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField("email", unique=True)
    username = models.CharField("username", unique=True, max_length=40)
    is_staff = models.BooleanField("is_staff", default=False)
    is_active = models.BooleanField("is_active", default=True)
    date_joined = models.DateTimeField("date_joined", default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = "username"
    EMAIL_FIELD = "email"
    REQUIRED_FIELDS = [] # ここが空

    class Meta:
        verbose_name = "user"
        verbose_name_plural = "users"
```

# 解決方法 : REQUIRED_FIELDS を埋める

そもそも `createsuperuser` 実行時にメールアドレスを聞かれなかったので、このあたりがおかしい
ユーザ作成時の必須項目を決める `REQUIRED_FIELD` の設定が空だったので、こちらを埋めてみる

```py
class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField("email", unique=True)
    username = models.CharField("username", unique=True, max_length=40)
    is_staff = models.BooleanField("is_staff", default=False)
    is_active = models.BooleanField("is_active", default=True)
    date_joined = models.DateTimeField("date_joined", default=timezone.now)

    objects = UserManager()

    USERNAME_FIELD = "username"
    EMAIL_FIELD = "email"
    REQUIRED_FIELDS = ["email"] # email を追加

    class Meta:
        verbose_name = "user"
        verbose_name_plural = "users"
```

↓

ユーザ作成時にEmailを聞かれるようになって、無事作成可能に
※modelsを書き換えたので、実行前にmigrateを実行しておく

```
$ python manage.py migrate

$ python manage.py createsuperuser
Username: superuser   
Email: hogehuga@gmail.com
Password: 
Password (again): 
Superuser created successfully.
```

## 【備考】USERNAME_FIELD はデフォルトで必須

`USERNAME_FIELD`はデフォルトで必須項目のため、
`REQUIRED_FIELD`に入れると`migrate`時にエラーが発生した。

```py
    USERNAME_FIELD = "username"
    EMAIL_FIELD = "email"
    REQUIRED_FIELDS = ["username","email"]
```

```
$ python manage.py makemigrations
SystemCheckError: System check identified some issues:

ERRORS:
users.User: (auth.E002) The field named as the 'USERNAME_FIELD' for a custom user model must not be included in 'REQUIRED_FIELDS'.
        HINT: The 'USERNAME_FIELD' is currently set to 'username', you should remove 'username' from the 'REQUIRED_FIELDS'.
```

# 感想

- 柔軟性と複雑性はトレードオフかな

カスタムUserクラスを作ると柔軟に要素追加できる分、
ソースコードも見てある程度理解する必要もありますね、、
なかなか大変そうだ