将继承关系更改为Django模型中的OneToOne‍关系

问题描述 投票:2回答:1

我有带inheritance relationship的模型。我想将此关系转换为OneToOne‍‍‍‍‍‍‍‍关系,不删除项目中的任何数据。

这是模型的结构:

class BaseFieldsModel(models.Model):
    create_date = DateTimeField(auto_now_add=True,)
    update_date = DateTimeField(auto_now=True,)
    created_by = ForeignKey('UserManager.User', related_name='created_%(class)ss')  
    updated_by = ForeignKey('UserManager.User', related_name='updated_%(class)ss')  

class User(AbstractBaseUser,BaseFieldsModel):
    # Some fields


class Teacher(User):
    # Some fields

class Student(User): 
    # Some fields 

由于我在this设计中遇到的这个问题,直到我想恢复数据库之前,一切都很好。在新的数据库模型中,我想要这样的内容:((一对一关系)

class User(AbstractBaseUser,BaseFieldsModel):
    # Some fields


class Teacher(BaseFieldsModel):
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='student_user')
    # Some fields

class Student(BaseFieldsModel): 
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='teacher_user')
    # Some fields   

所以我确实运行了makemigrations

Migrations for 'UserManager':
  UserManager/migrations/0022_auto_20200425_1233.py
    - Change managers on student
    - Change managers on teacher
    - Add field create_date to student
    - Add field created_by to student
    - Add field update_date to student
    - Add field updated_by to student
    - Add field create_date to teacher
    - Add field created_by to teacher
    - Add field update_date to teacher
    - Add field updated_by to teacher
    - Alter field user_ptr on student
    - Alter field user_ptr on teacher

然后运行migrate并收到此错误:

django.core.exceptions.FieldError: Local field 'create_date' in class 'Student' clashes with field of the same name from base class 'User'.

#测试过的解决方案

1。第一个失败的解决方案:

创建TeacherStudent,而没有继承形式BaseFielsModel

class User(AbstractBaseUser,BaseFieldsModel):
    # Some fields


class Teacher(models.Model):
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='student_user')

    create_date = DateTimeField(auto_now_add=True,)
    update_date = DateTimeField(auto_now=True,)
    created_by = ForeignKey('UserManager.User', related_name='created_%(class)ss')  
    updated_by = ForeignKey('UserManager.User', related_name='updated_%(class)ss')  

    # Some other fields

class Student(models.Model): 
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='teacher_user')

    create_date = DateTimeField(auto_now_add=True,)
    update_date = DateTimeField(auto_now=True,)
    created_by = ForeignKey('UserManager.User', related_name='created_%(class)ss')  
    updated_by = ForeignKey('UserManager.User', related_name='updated_%(class)ss')  

    # Some other fields 

然后运行makemigrations

Migrations for 'UserManager':
  UserManager/migrations/0022_auto_20200425_1240.py
    - Change managers on student
    - Change managers on teacher
    - Add field create_date to student
    - Add field created_by to student
    - Add field update_date to student
    - Add field updated_by to student
    - Add field create_date to teacher
    - Add field created_by to teacher
    - Add field update_date to teacher
    - Add field updated_by to teacher
    - Alter field user_ptr on student
    - Alter field user_ptr on teacher

然后migrate并再次引发错误:

django.core.exceptions.FieldError: Local field 'create_date' in class 'Student' clashes with field of the same name from base class 'User'.

2。第二失败的解决方案:

不创建Teacher及其字段的[创建StudentBaseFielsModel

class User(AbstractBaseUser,BaseFieldsModel):
    # Some fields


class Teacher(models.Model):
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='student_user')

    # Some other fields

class Student(models.Model): 
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='teacher_user')
    # Some other fields

然后运行makemigrations

Migrations for 'UserManager':
  UserManager/migrations/0022_auto_20200425_1243.py
    - Change managers on student
    - Change managers on teacher
    - Alter field user_ptr on student
    - Alter field user_ptr on teacher

并运行migrate

 Applying UserManager.0022_auto_20200425_1243... OK

然后将这些字段添加到StudentTeacher

create_date = DateTimeField(auto_now_add=True,)
    update_date = DateTimeField(auto_now=True,)
    created_by = ForeignKey('UserManager.User', related_name='created_%(class)ss')  
    updated_by = ForeignKey('UserManager.User', related_name='updated_%(class)ss')  

然后运行makemigrations

Migrations for 'UserManager':
  UserManager/migrations/0023_auto_20200425_1245.py
    - Add field create_date to student
    - Add field created_by to student
    - Add field update_date to student
    - Add field updated_by to student
    - Add field create_date to teacher
    - Add field created_by to teacher
    - Add field update_date to teacher
    - Add field updated_by to teacher

migrate

django.core.exceptions.FieldError: Local field 'create_date' in class 'Student' clashes with field of the same name from base class 'User'.

3。第三种成功的解决方案(错误的做法)

重命名与User模型中的字段冲突的所有字段:

class User(AbstractBaseUser,BaseFieldsModel):
    # Some fields


class Teacher(models.Model):
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='student_user')

    teacher_create_date = DateTimeField(auto_now_add=True,)
    teacher_update_date = DateTimeField(auto_now=True,)
    teacher_created_by = ForeignKey('UserManager.User', related_name='created_%(class)ss')  
    teacher_updated_by = ForeignKey('UserManager.User', related_name='updated_%(class)ss') 

    # Some other fields

class Student(models.Model): 
    user_ptr = OneToOneField('UserManager.User', primary_key=True,related_name='teacher_user')

    student_create_date = DateTimeField(auto_now_add=True,)
    student_update_date = DateTimeField(auto_now=True,)
    student_created_by = ForeignKey('UserManager.User', related_name='created_%(class)ss')  
    student_updated_by = ForeignKey('UserManager.User', related_name='updated_%(class)ss') 
    # Some other fields

然后makemigrations

Migrations for 'UserManager':
  UserManager/migrations/0023_auto_20200425_1335.py
    - Add field student_create_date to student
    - Add field student_created_by to student
    - Add field student_update_date to student
    - Add field student_updated_by to student
    - Add field teacher_create_date to teacher
    - Add field teacher_created_by to teacher
    - Add field teacher_update_date to teacher
    - Add field teacher_updated_by to teacher

最后是migrate

  Applying UserManager.0023_auto_20200425_1335... OK

完成!

Django有什么问题? XD

python django django-models django-migrations django-inheritance
1个回答
0
投票

表示您在用户模型中已经有一个名为“ create_date”的字段。您无需在教师和学生模型中再次添加它们。

© www.soinside.com 2019 - 2024. All rights reserved.