【问题标题】:Migrating from django user model to a custom user model从 django 用户模型迁移到自定义用户模型
【发布时间】:2017-08-05 06:34:49
【问题描述】:

我正在关注这两个参考(onetwo)来拥有一个自定义用户模型,以便通过电子邮件进行身份验证,并为其添加一个额外的字段。

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        unique=True,
        max_length=254,
    )
    mobile_number = models.IntegerField(unique=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = UserManager()
    ...
    ...    
    class Meta:
        db_table = 'auth_user'
    ...
    ...

如您所见,我已将db_table='auth_user' 添加到类的元字段中。此外,我已将 AUTH_USER_MODEL = 'accounts.User' 和用户模型应用程序(即帐户)包含在 settings.py 中的 INSTALLED_APPS 中。此外,我从应用程序中删除了迁移文件夹。

然后尝试迁移:

$ python manage.py makemigrations accounts
Migrations for 'accounts':
  accounts/migrations/0001_initial.py:
    - Create model User

$ python manage.py migrate accounts

这给了我一个错误:

django.db.migrations.exceptions.InconsistentMigrationHistory:迁移 admin.0001_initial 在其依赖项 accounts.0001_initial 之前应用于数据库“默认”。

如何从现有的 django 用户模型迁移到自定义用户模型?

【问题讨论】:

  • 您是否清除了django_migrations 表中的任何旧条目?
  • @nik_m 不。我应该清除所有数据库吗?
  • 清除它。只是为了确保你有一张新鲜的桌子。之后运行 makemigrations 并再次迁移。
  • @nik_m 不,我没有清除数据库。实际上数据库中有一些数据。不删除数据库就没有其他方法可以迁移吗?
  • Hmm... 似乎在admin.0001_initial.py 迁移文件中,您有一个尚未应用的accounts.0001_initial.py 迁移依赖项(元组列表)。这就是错误的原因。在您提供的第一个链接中,它显示截断django_migrations。你做到了吗?

标签: django django-migrations


【解决方案1】:

您必须从迁移历史记录中清除 admin、auth、contenttypes 和 session,并删除表。首先,删除应用程序的迁移文件夹,然后键入以下内容:

python manage.py migrate admin zero
python manage.py migrate auth zero
python manage.py migrate contenttypes zero
python manage.py migrate sessions zero

之后,您可以运行makemigrations accountsmigrate accounts

【讨论】:

    【解决方案2】:

    解决方案是撤消您现有的依赖于 AUTH_USER_MODEL 的迁移,如 in this answer 所述。如果您尝试撤消 admin、auth、contenttypes 和 session 的迁移,并且您收到如下错误:

    错误: auth.User.groups:(fields.E304)“User.groups”的反向访问器与“Profile.groups”的反向访问器冲突。 ....

    • 首先在 settings.py 中注释掉/撤消 AUTH_USER_MODEL(如果您已更改)。
    • 其次,在 settings.py 中注释掉/撤消包含来自 INSTALLED_APPS 的新 AUTH_MODEL 的 django 应用。
    • 现在您应该能够撤消身份验证、管理员、内容类型和会话的迁移,如下所示:
    python manage.py migrate admin zero
    python manage.py migrate auth zero
    python manage.py migrate contenttypes zero
    python manage.py migrate sessions zero
    
    • 现在将您的身份验证模型应用添加到 INSTALLED_APPS 并再次在 settings.py 中设置 AUTH_USER_MODEL
    • 运行:python manage.py migrate AUTH_APP,您可能还需要为您的身份验证模型应用程序进行迁移:python manage.py makemigrations AUTH_APP

    • 应用您撤消的所有迁移:python manage.py migrate

    你已经完成了。

    注意:您将丢失数据库中存在的所有现有用户。

    【讨论】:

    • 这是正确答案,因为它保留了现有数据。
    【解决方案3】:

    在我的特定情况下,其他答案没有帮助(即使在我尝试使用 migrate ... zero 删除表之后,即使我删除了迁移文件夹,错误仍然发生),以下帮助,但是 我刚开始,因此只需删除第一次迁移时创建的db.sqlite3 文件是没有问题的。 (根据您的 settings.py,您可能有不同的数据库文件)。

    如果您确定不会丢失数据库文件中的重要数据(例如,您还没有存储在数据库中的太多信息并且重新开始并不困难),您确实只能这样做,并且您将需要再次迁移所有内容。

    【讨论】:

      【解决方案4】:

      从数据库中删除现有的所有表。[注意:数据将丢失]

      从所有应用中删除 pycache 和迁移。

      为您的相关应用运行迁移

      python manage.py makemigrations users
      

      将表迁移到数据库

      python manage.py migrate
      

      【讨论】:

        【解决方案5】:

        你需要运行:

        python manage.py makemigrations accounts
        

        执行初始 manage.py migrate 之前(我的意思是在您第一次在项目上运行 migrate 时)

        建议在项目开始时设置自定义用户模型,以便在创建 admin、auth、contenttypes、sessions 表的同时迁移“帐户”应用。

        但如果您已经创建了表格,那么您应该按照@krishna-chandak 描述的说明进行操作:https://stackoverflow.com/a/53599345/5950111

        您可以阅读文档:https://docs.djangoproject.com/en/2.0/topics/auth/customizing/#using-a-custom-user-model-when-starting-a-project

        【讨论】:

          【解决方案6】:

          在您之前的迁移之后,您的数据库中有一个 django_migrations 表,这是造成这种不一致的原因。 解决方案:从数据库中删除 django_migrations 表。 从您的应用中删除迁移文件夹

          然后执行

          python3 manage.py makemigrations 
          python3 manage.py migrate
          

          【讨论】:

            【解决方案7】:

            我知道这是一个相当老的问题,但对于像我这样在谷歌上搜索这个主题的人来说,这里有一个解决方案,无需删除迁移、删除表和其他讨厌的东西)

            https://www.caktusgroup.com/blog/2019/04/26/how-switch-custom-django-user-model-mid-project/

            【讨论】:

              【解决方案8】:

              我有类似的问题,我必须在项目中间引入自定义用户模型。因此,以下步骤帮助我解决了这个问题,而不会丢失表或数据丢失。

              (1) 为应用创建初始空迁移(“帐户”)

              python manage.py makemigrations accounts --empty
              

              (2) 运行迁移

              python manage.py migrate
              

              (3) 更新数据库中 django_migrations 表中的时间戳,用于 'accounts' 初始迁移到 'admin' 初始时间戳。

              UPDATE django_migrations SET applied=<<admin 0001_initial date>> WHERE app='accounts' and name='0001_initial'; 
              

              (4) 现在创建没有任何字段的自定义用户模型(从 AbstractUser 派生),并将表名设置为 auth_user。您基本上是在重新使用数据库中现有的 auth 用户表。

              class User(AbstractUser):
                  class Meta:
                      db_table = 'auth_user'
              

              (4) 现在运行迁移,并将迁移复制到 0001_initial 并从依赖数组中删除“0001_initial”。同时删除新创建的迁移文件。

              python manage.py makemigrations accounts
              cp accounts/migrations/0002_user.py accounts/migrations/0001_initial.py
              edit the file 0001_initial.py
              rm accounts/migrations/0002_user.py  (remove migration file)
              

              (5) 现在添加您的自定义字段,运行 makemigrations 并照常迁移。

              【讨论】:

                【解决方案9】:

                我也遇到了同样的问题。我按照以下步骤操作:

                1. models.py 中,我设置了基本的User 模型
                # accounts/models.py
                class User(AbstractBaseUser):
                    class Meta:
                        db_table = 'auth_user'
                
                1. 然后,我运行makemigrations命令生成迁移文件
                $ python manage.py makemigrations accounts
                Migrations for 'accounts':
                  accounts/migrations/0001_initial.py:
                    - Create model User
                
                1. 下一步,我插入的记录有 0001_initial todjango_migrations
                $ echo "INSERT INTO django_migrations (app, name, applied) VALUES ('accounts', '0001_initial', CURRENT_TIMESTAMP);" | python manage.py dbshell
                
                1. 更新模型中的最新版本
                # accounts/models.py
                class User(AbstractBaseUser, PermissionsMixin):
                    email = models.EmailField(
                        unique=True,
                        max_length=254,
                    )
                    mobile_number = models.IntegerField(unique=True)
                    is_active = models.BooleanField(default=True)
                    is_admin = models.BooleanField(default=False)
                
                    objects = UserManager()
                    ...
                    ...    
                    class Meta:
                        db_table = 'auth_user'
                    ...
                    ...
                
                1. 我需要再次进行迁移

                运行 makemigrations 后,我有了下一个迁移文件。

                0002_....py
                
                1. 再次迁移
                python manage.py migrate.
                

                【讨论】:

                  【解决方案10】:

                  对我有用的是我从这里给出的所有不同的解决方案中拼凑出来的一个解决方案。

                  我检查数据库是否存在,因为我对现有数据库没有问题,仅当数据库为空时。

                  # check if the database exists
                  db_ok=false
                  if python ./manage.py check; then
                    db_ok=true
                  fi
                  
                  if [ $db_ok = true ]; then
                    # database exists: do a normal migrate
                    python ./manage.py migrate
                  else
                    # database does not exists, make and migrate users then a migrate and cleanup of the users migraton
                    python ./manage.py makemigrations users
                    python ./manage.py migrate users
                    python ./manage.py migrate
                    rm -r users/migrations/
                  fi
                  

                  【讨论】:

                    【解决方案11】:

                    迁移归零对我没有帮助。我不得不删除整个数据库:

                    sudo -u postgres psql
                    drop database YOURDATABASENAME;
                    create database YOURDATABASENAME;
                    

                    然后:

                    python ./manage.py makemigrations MYAPPNAME
                    python ./manage.py migrate MYAPPNAME
                    python ./manage.py migrate
                    

                    在这些之后我继续前进..

                    【讨论】:

                    • 因为一个小的迁移错误而删除整个数据库就像因为它的轮胎漏气而将你的汽车着火......
                    猜你喜欢
                    • 1970-01-01
                    • 2015-10-10
                    • 2015-08-20
                    • 1970-01-01
                    • 2018-05-26
                    • 2012-12-26
                    • 2016-10-07
                    • 1970-01-01
                    相关资源
                    最近更新 更多