Django

DjangoでSuperuser created successfully.となるもログインできずハマった

表題の通り、DjangoでSuperuser created successfully.となるもログインできずハマり1日潰しました。

結論から言って誤字だったのですが、勉強中のためなぜこんなことになるのかエラーも吐かないため全く理解できず1日無駄に過ごすこととなりました。

またcreated successfullyとなったものの同じメールアドレスでユーザー登録できてしまい、ユーザーがつくられていないのでは?とうたがったこともハマった原因でした。もっと信じてあげればよかった。

結局誤字だった

誤字を最初に疑ったものの知識がないので誤字を見つけられず、また他の誤字もあったりして直した気でいた。

間違っていた箇所は以下。

from django.db import models
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin, BaseUserManager

class UserManager(BaseUserManager):
    def create_user(self, email, name, password=None):
        if not email:
            raise ValueError('Users must have an email')
        
        email = self.normalize_email(email)
        email = email.lower() # email = email.lowerにして()が抜けていた

        user = self.model(
            email=email,
            name=name
        )

        user.set_password(password)
        user.save(using=self._db)

        return user
    
    def create_superuser(self, email, name, password=None):
        user = self.create_user(email, name, password)
        user.is_superuser = True
        user.is_staff = True
        
        user.save(using=self._db)
        return user

class UserAccount(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField("メールアドレス", max_length=225, unique=True) #max_length=255が正しい
    name = models.CharField("名前", max_length=255)

    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name']

    def __str__(self):
        return self.email

email = email.lower()の箇所でemail = email.lowerにして()が抜けていたこととmax_length=255が正しいところmax_length=225と書いていた。

そのため登録されていたデータを確認すると暗号のようなメールアドレス「例:<built-in method lower of str object at 0x10c9334b0>」とパスワード「例:egqogjcns&acnxotb…」が登録されていてデータをみてみるとこうなっていたのかとようやく原因が少し理解できました。

不思議なもので、email.lowerをemail.lower()に変更しmigrateしただけでは治らず、max_length=255にも直してようやくバグを解消できた。継承しているからなのか?

ハマった理由

データベースへログインできないので状況確認できないことで検討をつけられなかったこともあり、見当違いの場所をひたすら確認して時間を消耗してしまいました。

get_user_model()を疑った

仕組みがよくわかっていないので、カスタムユーザーの設定がうまく行っておらず間違ったデータベースに登録されているのではないかと勘ぐり

view.pyでおこなっていた

from django.contrib.auth import get_user_model
User = get_user_model()

でget_user_model()で本当に意図したデータベースとテーブルをみれているのかきになりだし、settings.pyのAUTH_USER_MODELの書き方が間違っていないか確認した。

AUTH_USER_MODEL = 'app_name.UserAccount'

app_nameにはアプリの名前が入っており、正しかったのですがこれであっているのか不安になり深みにハマった。

誤字が多すぎた

私の癖でもあるのですが、勉強中は多少のエラーが起きないと勉強にならないとおもっているので結構適当にコードを書いているのですが適当の度がすぎたようで二箇所誤字を見つけて修正したこともあり他の誤字もあったのに全て直した気でいたため気づけなかった。

migrationを疑った

modelsに誤字もあったためmakemigrationsとmigrateを複数行っているとmakemigrationsをおこなってもNo changes detectedと返ってきて本当にちゃんと反映されているのか不安になった。

実際にそんなこともあるようで、115designさんのDjangoでmigrateしてるのにDBに反映されない時の対処法【Djangoアウトプット】を実施したり。

既存のデータを削除してから作り直しをおこなってみたりした。

$ python3 manage.py makemigrations
$ rm -rf db.sqlite3
$ python3 manage.py migrate

おわり

エラーになってハマると少し成長できる気がするものの、このまま解決できずに挫折するのではないかとヒヤヒヤしますね。

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です