Django mptt数据库迁移错误

4
我可以帮您翻译成中文。这段内容是关于编程的,作者正在尝试在他的项目中使用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:

我该怎么办?

2个回答

4
"MPTTModel会自动添加“级别”以表示树中特定节点的深度。如果您尚未创建树结构,则选择选项1并将所有内容默认为级别0(根)应该是安全的。如果您尚未设置树结构,则这样做应该是可以的,并且在稍后使用树时会进行调整。
如果您已经有一个树结构并需要在数据中反映出来,那么仍然需要这样做,但您需要跟随一个(可能是手写的)data migration 来设置正确的值。"

只需记住,级别1是默认mptt模型的子级,该模型设置为0。 - Elias Prado

0

--- 2022年更新 ---

据我所见,您可以将levellftrghttree_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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接