Djangoアプリを構築する際にカスタムユーザーを作ることがあるのですが、毎回migrationができずにはまっています。
対処法をメモしておこうと思いました。
Djangoのversionは3.2.7
まずはいつも通りはまってみようと思います。
まずregister
というアプリにカスタムユーザーを定義します。
django-admin startproject project .
python manage.py startapp register
AbstractUser
を継承します。
# register/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
次にmigrationsを実行してみましょう。
python manage.py makemigrations
>>>
No changes detected
何もおきません。
だいたいここであせってmigrate
します。
python manage.py migrate
>>>
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
そうすると組み込みのユーザーモデルがmigrateされてしまいます。
焦っていなくても最初に組み込みのユーザーモデルで行っていて後から切り替えたい、ということもあります。
なので、結構あるパターンだと思います。
ここから解決をしていきましょう。
まず、以下の2か所の追記が必要です。
結構忘れやすいポイントです。
# project/settings.py
...
INSTALLED_APPS = [
'register.apps.RegisterConfig', # 追加
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
...
# 追加
AUTH_USER_MODEL = 'register.User'
...
さっそくmakemigrationをしてみましょう。
python manage.py makemigrations
>>>
register\migrations\0001_initial.py
- Create model User
無事にmigrationファイルができました。
しかしmigrateしようとするとerrorが起きます。
python manage.py migrate
>>>
Traceback (most recent call last):
File "manage.py", line 22, in <module>
main()
File "manage.py", line 18, in main
execute_from_command_line(sys.argv)
....
raise InconsistentMigrationHistory(
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency register.0001_initial on database 'default'.
やけくそになってcreatesuperuserを作ろうとしたりしますが、失敗します。
python manage.py createsuperuser
>>>
Traceback (most recent call last):
File "manage.py", line 22, in <module>
main()
File "manage.py", line 18, in main
execute_from_command_line(sys.argv)
...
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: no such table: register_user
当然ですが、register_userなんていうテーブルがないよ、と怒られているわけです。
とにかくmigrateしないと始まりません。
migrate時のエラーを注意深くみるとadminが悪さをしてることに気づきます。
adminに関する記述をコメントアウトすることでmigrateできるようになります。
# project/settings.py
INSTALLED_APPS = [
'register.apps.RegisterConfig', # 追加
# コメントアウト 'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
# project/urls.py
urlpatterns = [
# コメントアウト path('admin/', admin.site.urls),
]
実行してみます。
python manage.py migrate
>>>
Applying register.0001_initial... OK
うまくいきました。
そうしたらコメントアウトを解除して再びmigrateしましょう。
python manage.py migrate
>>>
Operations to perform:
Apply all migrations: admin, auth, contenttypes, register, sessions
Running migrations:
No migrations to apply.
これでオッケーです。
既にスーパーユーザーを作っていたら、もう一回createsuperuser
をします。
何もmigrateしていない状態で、settings.pyへの追記をきちんとしてから、makemigrations、migrateをすると一発でうまくいきます。