将django&#39的auth_user与现有用户表合并

时间:2017-09-08 07:09:01

标签: python mysql django django-rest-framework django-authentication

目前我有一个遗留应用,它引用了包含所有自定义字段的user表。由于有大量遗留代码引用该表,因此我不能简单地将该表重命名为auth_user。所以我试图做的事情是以某种方式合并(我不知道它是正确的术语)auth_useruser

以下是user表:

+-------------------+--------------+------+-----+---------+----------------+
| Field             | Type         | Null | Key | Default | Extra          |
+-------------------+--------------+------+-----+---------+----------------+
| user_id           | int(10)      | NO   | PRI | NULL    | auto_increment |
| name              | varchar(100) | NO   |     | NULL    |                |
| address           | varchar(100) | NO   |     | NULL    |                |
| phone_no          | varchar(15)  | NO   |     | NULL    |                |
| city              | varchar(100) | NO   |     | NULL    |                |
| state             | varchar(100) | NO   |     | NULL    |                |
| pin_no            | int(10)      | NO   |     | NULL    |                |
| type              | varchar(100) | NO   |     | NULL    |                |
| email             | varchar(100) | NO   |     | NULL    |                |
| password          | varchar(100) | NO   |     | NULL    |                |
| is_active         | tinyint(1)   | NO   |     | NULL    |                |
| role              | varchar(40)  | NO   |     | NULL    |                |
| creation_date     | int(100)     | NO   |     | NULL    |                |
| edit_date         | int(100)     | NO   |     | NULL    |                |
| country           | varchar(255) | NO   |     | NULL    |                |
| district          | varchar(255) | NO   |     | NULL    |                |
| ip                | varchar(255) | NO   |     | NULL    |                |
| added_by          | int(11)      | NO   |     | NULL    |                |
| is_phone_verified | binary(1)    | NO   |     | 0       |                |
| remember_token    | varchar(100) | YES  |     | NULL    |                |
| disclaimer_agreed | int(11)      | YES  |     | 0       |                |
| mobile_login      | tinyint(4)   | NO   |     | 0       |                |
+-------------------+--------------+------+-----+---------+----------------+

和django' auth_user表:

+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| password     | varchar(128) | NO   |     | NULL    |                |
| last_login   | datetime(6)  | YES  |     | NULL    |                |
| is_superuser | tinyint(1)   | NO   |     | NULL    |                |
| username     | varchar(150) | NO   | UNI | NULL    |                |
| first_name   | varchar(30)  | NO   |     | NULL    |                |
| last_name    | varchar(30)  | NO   |     | NULL    |                |
| email        | varchar(254) | NO   |     | NULL    |                |
| is_staff     | tinyint(1)   | NO   |     | NULL    |                |
| is_active    | tinyint(1)   | NO   |     | NULL    |                |
| date_joined  | datetime(6)  | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

我想要的是一个表,django将在使用contrib.auth相关内容时引用,同时也不会弃用我的遗留代码。也许是这样的:

+-------------------+--------------+------+-----+---------+----------------+
| Field             | Type         | Null | Key | Default | Extra          |
+-------------------+--------------+------+-----+---------+----------------+
| user_id           | int(10)      | NO   | PRI | NULL    | auto_increment |
| name              | varchar(100) | NO   |     | NULL    |                |
| address           | varchar(100) | NO   |     | NULL    |                |
| phone_no          | varchar(15)  | NO   |     | NULL    |                |
| city              | varchar(100) | NO   |     | NULL    |                |
| state             | varchar(100) | NO   |     | NULL    |                |
| pin_no            | int(10)      | NO   |     | NULL    |                |
| type              | varchar(100) | NO   |     | NULL    |                |
| email             | varchar(100) | NO   |     | NULL    |                |
| password          | varchar(100) | NO   |     | NULL    |                |
| is_active         | tinyint(1)   | NO   |     | NULL    |                |
| role              | varchar(40)  | NO   |     | NULL    |                |
| creation_date     | int(100)     | NO   |     | NULL    |                |
| edit_date         | int(100)     | NO   |     | NULL    |                |
| country           | varchar(255) | NO   |     | NULL    |                |
| district          | varchar(255) | NO   |     | NULL    |                |
| ip                | varchar(255) | NO   |     | NULL    |                |
| added_by          | int(11)      | NO   |     | NULL    |                |
| is_phone_verified | binary(1)    | NO   |     | 0       |                |
| remember_token    | varchar(100) | YES  |     | NULL    |                |
| disclaimer_agreed | int(11)      | YES  |     | 0       |                |
| mobile_login      | tinyint(4)   | NO   |     | 0       |                |
| last_login        | datetime(6)  | YES  |     | NULL    |                |
| is_superuser      | tinyint(1)   | NO   |     | NULL    |                |
| username          | varchar(150) | NO   | UNI | NULL    |                |
| first_name        | varchar(30)  | NO   |     | NULL    |                |
| last_name         | varchar(30)  | NO   |     | NULL    |                |
| is_staff          | tinyint(1)   | NO   |     | NULL    |                |
| is_active         | tinyint(1)   | NO   |     | NULL    |                |
| date_joined       | datetime(6)  | NO   |     | NULL    |                |
+-------------------+--------------+------+-----+---------+----------------+
  

这里的动机是利用Django的内置authenticationpermission系统,但不会破坏遗留代码。我认为必须有一个解决方案,因为这不是第一次有人将一些遗留应用程序移植到django。

我还想提一下这个链接How to Extend Django User Model,但我不确定哪种方法最好采用,或者我应该做一些完全不同的方法

2 个答案:

答案 0 :(得分:1)

Django明确支持自定义用户模型。为现有表创建模型,使其从AbstractBaseUser继承,并将{ "storeID" : "715R", "sensorID" : [ "0BBA", "0BB9" ] } { "storeID" : "312R", "sensorID" : [ "0BBB" ] } 设置设置为指向新模型。请参阅comprehensive docs

答案 1 :(得分:0)

我们可以从Django ticket中详细了解如何从内置用户模型迁移到自定义用户模型。

引用Carsten Fuchs

假设

  • 您的项目还没有自定义用户模型。
  • 必须保留所有现有用户。
  • 没有挂起的迁移,所有现有的迁移都将应用。
  • 可以接受的是,即使您使用版本控制来签出旧版本,以前的所有迁移也都将丢失并且不再无法应用 提交仍具有迁移文件的提交。这是相关的 这种方法的缺点。

准备工作

  • 确保任何引用Django用户模型的第三方应用程序仅使用{generic referencing methods
  • 确保您自己的可重用应用程序(旨在供其他人使用的应用程序)使用通用引用方法。
  • 我建议不要对您的项目应用程序执行相同的操作:切换到自定义用户模型对于每个项目仅执行一次,而不再执行。它 将from django.contrib.auth.models import User更改为其他内容(如详细信息)更容易(我认为也更清晰) 下面),而不是将其替换为不需要的通用引用 在项目代码中。
  • 确保您已经备份了代码和数据库!

更新代码

  • 您可以在任何现有应用程序或新创建的应用程序中创建新的用户模型。我的偏好是创建一个新应用:

    ./manage.py startapp Accounts
    

我选择了“帐户”这个名称,但其他任何名称也可以使用。

  • Aymeric:创建一个与auth.User相同的自定义用户模型,将其命名为User(因此,许多表保持相同的名称)并进行设置 db_table='auth_user'(因此它使用相同的表)。“ Accounts/models.py

    from django.contrib.auth.models import AbstractUser
    from django.db import models
    
    
    class User(AbstractUser):
    class Meta:
            db_table = 'auth_user'
    
  • settings.py中,将应用程序添加到INSTALLED_APPS并更新AUTH_USER_MODEL设置:

    INSTALLED_APPS = (
        # ...
        'Accounts',
    )
    
    AUTH_USER_MODEL = 'Accounts.User'
    
  • 在您的项目代码中,替换所有导入的Django用户模型:

    from django.contrib.auth.models import User with the new, custom one:
    

    从Accounts.models导入用户

  • 删除所有旧的迁移。 (之前,请查看comment 14是否与您相关!)例如,在项目根目录中:

    find . -path "*/migrations/*.py" -not -name "__init__.py" -delete
    find . -path "*/migrations/*.pyc" -delete
    
  • 从头开始创建新迁移:

    ./manage.py makemigrations
    
  • 根据需要对admin.py文件进行任何更改。 (我无法在此处提供任何可靠的信息,但这对于结果和 因此详细信息以后仍可以查看。)

  • 确保您的测试套件成功完成! (必须使用新的测试数据库,不能将其保留在以前的运行中。)
  • 至此,对代码的更改已完成。这是提交的好时机。

请注意,我们已经完成了–除了新的迁移文件不匹配 django_migrations表的内容。

(此时甚至可以为您的项目提供服务: 在实际更改数据库之前可以轻松撤消。 如果您了解自己甚至无法触摸迁移, 系统,只要以下步骤没有完成!)

更新数据库

  • 截断django_migrations表。 MySQL 8示例:

      TRUNCATE TABLE django_migrations;
    

对于其他数据库或MySQL版本,这可能有所不同< 8。

  • 伪造一组新的迁移 ./manage.py迁移--fake

  • 按照comment 12

  • 所述检查ContentTypes

结论

  • 到定制用户模型的升级现已完成。您可以对此模型进行更改,并为其生成并应用迁移 任何其他型号。
  • 第一步,您可能希望取消设置db_table并生成并应用结果迁移。
  • 我认为,startproject管理命令应该可以预期引入自定义用户模型。