从 django 用户模型迁移到自定义用户模型

Posted

技术标签:

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

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

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。你做到了吗? 【参考方案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://***.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】:

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

    models.py 中,我设置了基本的User 模型
# accounts/models.py
class User(AbstractBaseUser):
    class Meta:
        db_table = 'auth_user'
    然后,我运行makemigrations命令生成迁移文件
$ python manage.py makemigrations accounts
Migrations for 'accounts':
  accounts/migrations/0001_initial.py:
    - Create model User
    下一步,我插入的记录有 0001_initial todjango_migrations
$ echo "INSERT INTO django_migrations (app, name, applied) VALUES ('accounts', '0001_initial', CURRENT_TIMESTAMP);" | python manage.py dbshell
    更新模型中的最新版本
# 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'
    ...
    ...
    我需要再次进行迁移

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

0002_....py
    再次迁移
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

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

【讨论】:

因为一个小的迁移错误而删除整个数据库就像因为它的轮胎漏气而将你的汽车着火......

以上是关于从 django 用户模型迁移到自定义用户模型的主要内容,如果未能解决你的问题,请参考以下文章

Django 管理员无法使用自定义用户模型正确登录

使用注册表单添加到自定义用户字段(django)

如何将自定义用户模型迁移到 Django 中的不同应用程序?

Django 1.8 迁移、自定义用户模型和 Postgres/MySQL 的奇怪问题

将现有 auth.User 数据迁移到新的 Django 1.5 自定义用户模型?

将扩展的 Profile 模型添加到自定义用户模型 admin