问题描述
假设我有以下基本模型:
Lets say i have the following base model:
class human(models.Model):
gender = models.BooleanField()
age = models.IntegerField()
name = models.CharField(max_length=200)
还有两个继承它的模型:
And two models inheriting it:
class superhero(human):
can_fly = models.BooleanField()
class villain(human):
fingerprint = models.ImageField()
在我的开发过程中的某个时候,我意识到我实际上并不直接需要人类类.我只需要它是一组超级英雄和反派模型的模板参数.如果现在我转到人类 Meta
类并设置 abstract=True
并像这样更改我的模型:
At some time in my development process i realized that i don't actually need the human class directly. I only need it to be a set of template parameters for superhero and villain models. If now i go to human Meta
class and set abstract=True
and change my models like so:
class human(models.Model):
gender = models.BooleanField()
age = models.IntegerField()
name = models.CharField(max_length=200)
class Meta:
abstract = True
class superhero(human):
can_fly = models.BooleanField()
class villain(human):
fingerprint = models.ImageField()
尝试进行迁移和迁移将引发以下错误
attempt to make migrations and migrate will raise the following error
'superhero' 类中的本地字段 u'gender' 与基类 'human' 中名称相似的字段发生冲突
如何在不直接修改数据库的情况下切换到抽象类以保留所有迁移?
How can i switch to abstract class keeping all my migrations without tinkering the database directly?
推荐答案
所以在再次阅读文档后我找到了一个解决方案:
由于 Django 将模型保存到数据库的方式而引发的错误.从基本模型 human
继承的所有模型在它们自己的表中都没有所有 human
字段.相反,它们只有自己的字段和将它们链接到 human
表中相应行的外键.但是当您从抽象类继承时,所有字段都直接保存到模型的表中.因此,当我尝试将 human
类更改为 abstract=True
并在 superhero
类中继承它时,Django 尝试从 human 创建所有字段
表,该表仍然具有指向现有人类条目的外键,其字段名称完全相同.superhero
表中的
So after reading the docs again I found a solution:
The error was raised because of the way Django saves models to the database. All models that inherit from the base model human
don't have all human
fields in their own tables. Instead they have only their own fields and a foreign key that links them to the corresponding lines in human
table. But when you inherit from abstract class all the fields are saved directly to your model's table. So when I tried to change human
class to abstract=True
and inherit it in superhero
class Django tried to create all fields from human
table in superhero
table, which still has a foreign key to existing human entry with fields named exactly the same.
按照这个指令会得到想要的结果,但不幸的是会破坏所有条目 human
superhero
和 villain
模型
Following this instruction will make the desired result but unfortunately will destroy all entries of human
superhero
and villain
models
- 评论
superhero
和villain
模型,以便 Django 删除它们 - 进行迁移和迁移,以便删除
superhero
和villain
表 - 在
human
类 中设置 - 进行迁移并再次迁移.这将删除
human
表,因为它现在是一个抽象类 - 取消注释
superhero
和villain
模型 - 进行迁移和迁移.这将创建
villain
和superhero
表,其中包含human
类 的所有字段
abstract=True
- Comment
superhero
andvillain
models so Django deletes them - Make migrations and migrate so the
superhero
andvillain
tables are deleted - Set
abstract=True
inhuman
class - Make migrations and migrate again. This will delete
human
table because now it is an abstract class - Uncomment
superhero
andvillain
models - Make migrations and migrate. This will create
villain
andsuperhero
tables with all the fields fromhuman
class
就是这样.
附言为什么我需要转到抽象类?因为我想使用 unique_together
参数使我所有的 villains
和 superheroes
都是独一无二的,这会产生一些数据库级别的限制.为了使这成为可能,所有 superhero
字段都必须在一个表中.现在它可以工作了.
P.S. Why I needed to move to abstract class? Because I wanted to make all my villains
and superheroes
unique using unique_together
parameter that makes some DB level restrictions. To make this possible all superhero
fields had to be in one table. Now it works.
这篇关于如果django模型已经有相关类,如何将其转换为抽象模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!