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が入ってこないから発生していると思われる
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)
この時点でのカスタムユーザモデルはこちら
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
の設定が空だったので、こちらを埋めてみる
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
時にエラーが発生した。
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クラスを作ると柔軟に要素追加できる分、
ソースコードも見てある程度理解する必要もありますね、、
なかなか大変そうだ