django.db.migrations.exceptions.InconsistentMigrationHistory エラー対処


# はじめに
DjangoでWeb開発をしていたとき、Migrationエラーに結構時間がかかったので、自分が対処した経緯を残す。
# 環境
Mac Catalina 10.15.6
Python 3.7
PostgreSQL 10.14
Django 2.2.2

# Migration
### makemigrations
    $ python manage.py makemigrations
    django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency user.0001_initial on database 'default'
エラーは、CustomUserモデルを適用する前に一度でも `python manage.py makemigrations` した場合に起きるらしい . . .

### migrate
    $ python manage.py migrate
    RuntimeError: Model class django.contrib.sites.models.Site doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
もちろん、`migrate`の方もダメでした。

# 現状のMigrations状況を確認
    $ python manage.py showmigrations
これでエラーが出ると、そもそもMigrateできていないということ。
# 対処
## 対処1
まずは、それぞれのアプリの`migrations`直下の`__init__.py`以外のファイルを全て削除する。　　

次にsettings.pyにあるINSTALLED_APPS一番上の'django.contrib.admin'部分をコメントアウト。
    
    ＃*****　settings.py　********
    
    $ INSTALLED_APPS = [
        # 'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'accounts'
    ]

    AUTH_USER_MODEL = 'accounts.CustomUser'
さらに、`urls.py`の`urlpatterns`のadmin部分をコメントアウト。

    #*****  urls.py  *******

    from django.contrib import admin
    from django.urls import path
    from django.urls.conf import include

    urlpatterns = [
       # path('admin/', admin.site.urls),
    ]

これで一旦`migrate`を行ってみよう。うまくいけば通る。

## 対処2
[対処1](## 対処1)と同じように、それぞれのアプリの`migrations`直下の`__init__.py`以外のファイルを全て削除する。　　

### データベースごと削除して作り直す
実際、自分は[対処1](## 対処1)ではエラーは直せなかったので、この方法で、データベースを再構築することで`makemigrations`、`migrate`に成功した。
ここでは`postgresql@10`を使用している。
#### データベースについては[こちら](https://qiita.com/kanzaki0507/items/12a2ef0b778250d699bd)

### データベースを確認
    $ psql -l

                                 List of databases
    Name      |  Owner  | Encoding |   Collate   |    Ctype    |  Access 
                                                               |  privileges  
    ---------------+---------+----------+-------------+-------------+---------
    postgres   | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | 
    app_name   | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | 
    template0  | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | =c/kanzaki  +
               |         |        |             |             | kanzaki=CTc/ 
               |         |        |             |             | kanzaki
    template1  | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | =c/kanzaki  +
               |         |        |             |             | kanzaki=CTc/ 
               |         |        |             |             | kanzaki
    (4 rows)
### デーベースを削除する
    $ dropdb app_name 
### データベースが削除されていることを確認
    $ psql -l
    
                                 List of databases
    Name      |  Owner  | Encoding |   Collate   |    Ctype    |  Access 
                                                               |  privileges  
    ---------------+---------+----------+-------------+-------------+---------
    postgres   | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | 
    template0  | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | =c/kanzaki  +
               |         |        |             |             | kanzaki=CTc/ 
               |         |        |             |             | kanzaki
    template1  | kanzaki | UTF8   | en_US.UTF-8 | en_US.UTF-8 | =c/kanzaki  +
               |         |        |             |             | kanzaki=CTc/ 
               |         |        |             |             | kanzaki
    (3 rows)

### データベースを再構築
    $ brew services start postgresql@10
    $ create app_name

# makemigrations & migrate
    $ python manage.py migrate
    Operations to perform:
      Apply all migrations: account, accounts, admin, auth, contenttypes, diary, 
    sessions, sites
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying contenttypes.0002_remove_content_type_name... OK
      Applying auth.0001_initial... 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 accounts.0001_initial... OK
      Applying account.0001_initial... OK
      Applying account.0002_email_max_length... OK
      Applying admin.0001_initial... OK
      Applying admin.0002_logentry_remove_auto_add... OK
      Applying admin.0003_logentry_add_action_flag_choices... OK
      Applying diary.0001_initial... OK
      Applying sessions.0001_initial... OK
      Applying sites.0001_initial... OK
      Applying sites.0002_alter_domain_unique... OK
無事にできましたか？

# まとめ
今回は、DjangoでWeb開発している際にかなりハマった一部分を記事にまとめました。
DBを再構築することでMigrationできましたが、この方法を示した記事はあまりなかったので書きました。
こんな方法でも解決できることを知らせたかったです。

# 参考
[Django は必ず CustomUserモデルを使え！という話](https://hackmd.io/@AKLoPcIvSIqmV3io_RigWQ/Bkzxn9u0B)
[Django カスタムユーザーのマイグレーションに失敗するときの対処法](https://tech-k-labs.xyz/post/server_side/django_migrate_custom_user/)