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:

我应该怎么办?

4

2 回答 2

4

MPTTModel 自动添加“级别”以表示树中特定节点的“深度”。如果您还没有创建树结构,那么选择选项 1 并将所有内容默认为级别 0(根)应该是安全的。如果您还没有设置树结构,这应该没问题,并且应该在您稍后使用树时进行调整。

如果您已经考虑了树结构并且需要在数据中反映它,您仍然需要这样做,但您需要按照它进行(可能是手写的)数据迁移以设置正确的值。

于 2015-05-26T21:33:25.477 回答
0

--- 2022 年更新 ---

据我所知,您可以将 、 和 的所有内容level设置lftrght0 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
}

然后你需要进入外壳并重建所有树:

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

于 2022-02-16T15:24:16.027 回答