我有带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。第一个失败的解决方案:
创建Teacher
和Student
,而没有继承形式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
及其字段的[创建Student
和BaseFielsModel
:
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
然后将这些字段添加到Student
和Teacher
:
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
表示您在用户模型中已经有一个名为“ create_date”的字段。您无需在教师和学生模型中再次添加它们。