Django mptt数据库迁移报错
Django mptt database migration error
我正在尝试让 mptt 与我当前的项目一起使用,但在数据库迁移方面遇到问题。
这是我的模型
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
class Section(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
class MPTTMeta:
order_insertion_by = ['name']
并在命令行中输入 运行:
sudo python manage.py makemigrations core
但似乎出现了与级别字段相关的错误
You are trying to add a non-nullable field 'level' to section without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:
我该怎么办?
'Level' 由 MPTTModel 自动添加以表示树中特定节点的 'depth'。如果您还没有创建树结构,那么选择选项 1 并将所有内容默认设置为 0 级(根)应该是安全的。如果您还没有设置树结构,这应该没问题,并且应该在您稍后使用树时进行调整。
如果您已经有了一个树结构并且需要在您的数据中反映出来,您仍然需要这样做,但是您需要在它后面加上一个(可能是手写的)data migration设置正确的值。
--- 2022 年更新 ---
据我所知,您可以将 level
、lft
、rght
和 tree_id
:
的所有内容都设置为 0
例如:
You are trying to add a non-nullable field 'level' to section without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:
将所有值设置为零并迁移后,树将如下所示:
{
"id": 1,
"name":"first test tree",
"lft": 0,
"rght": 0,
"tree_id": 0,
"level": 0,
"parent": null
}
然后你需要进入 shell 并重建所有树:
Section.objects.rebuild()
完成重建命令后,您的树将设置为正常状态,能够创建新的子树:
{
"id": 1,
"name": "first test tree",
"lft": 1,
"rght": 2,
"tree_id": 1,
"level": 0,
"parent": null
}
其他方法:
您还可以在保存后在模型中添加 rebuild()
命令;非常适合那些无法访问数据库或生产终端的人:
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
class Section(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
class MPTTMeta:
order_insertion_by = ['name']
def save(self, *args, **kwargs):
# before save
super(Section, self).save(*args, **kwargs)
# after save...
try:
# get all objects from the Section table.
trees = Section.objects.all()
# loops through all values.
for tree in trees:
# checks if there is default=0 and if yes rebuild the trees.
if tree.lft or tree.rght or tree.tree_id == 0:
Section.objects.rebuild()
except Exception as e:
print(e)
pass
我正在尝试让 mptt 与我当前的项目一起使用,但在数据库迁移方面遇到问题。
这是我的模型
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
class Section(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
class MPTTMeta:
order_insertion_by = ['name']
并在命令行中输入 运行:
sudo python manage.py makemigrations core
但似乎出现了与级别字段相关的错误
You are trying to add a non-nullable field 'level' to section without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:
我该怎么办?
'Level' 由 MPTTModel 自动添加以表示树中特定节点的 'depth'。如果您还没有创建树结构,那么选择选项 1 并将所有内容默认设置为 0 级(根)应该是安全的。如果您还没有设置树结构,这应该没问题,并且应该在您稍后使用树时进行调整。
如果您已经有了一个树结构并且需要在您的数据中反映出来,您仍然需要这样做,但是您需要在它后面加上一个(可能是手写的)data migration设置正确的值。
--- 2022 年更新 ---
据我所知,您可以将 level
、lft
、rght
和 tree_id
:
例如:
You are trying to add a non-nullable field 'level' to section without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option:
将所有值设置为零并迁移后,树将如下所示:
{
"id": 1,
"name":"first test tree",
"lft": 0,
"rght": 0,
"tree_id": 0,
"level": 0,
"parent": null
}
然后你需要进入 shell 并重建所有树:
Section.objects.rebuild()
完成重建命令后,您的树将设置为正常状态,能够创建新的子树:
{
"id": 1,
"name": "first test tree",
"lft": 1,
"rght": 2,
"tree_id": 1,
"level": 0,
"parent": null
}
其他方法:
您还可以在保存后在模型中添加 rebuild()
命令;非常适合那些无法访问数据库或生产终端的人:
from django.db import models
from mptt.models import MPTTModel, TreeForeignKey
class Section(MPTTModel):
name = models.CharField(max_length=50, unique=True)
parent = TreeForeignKey('self', null=True, blank=True, related_name='children', db_index=True)
class MPTTMeta:
order_insertion_by = ['name']
def save(self, *args, **kwargs):
# before save
super(Section, self).save(*args, **kwargs)
# after save...
try:
# get all objects from the Section table.
trees = Section.objects.all()
# loops through all values.
for tree in trees:
# checks if there is default=0 and if yes rebuild the trees.
if tree.lft or tree.rght or tree.tree_id == 0:
Section.objects.rebuild()
except Exception as e:
print(e)
pass