django-mptt引发django.db.utils.IntegrityError:“lft”列中的空值违反非空约束

时间:2015-12-30 17:27:00

标签: django migration mptt

条件:Django == 1.8.7иdjango-mptt == 0.8.0。

有一个模型:

class Tree(mptt_models.MPTTModel):
    name = models.CharField(max_length=120, unique=True)
    slug = models.SlugField(max_length=256, unique=True)
    parent = mptt_models.TreeForeignKey('self', null=True, blank=True,
                                        related_name='children', db_index=True)

    class MPTTMeta:
        order_insertion_by = ['name']

我可以用管理界面填写它并在网站页面上显示。

我可以用django shell填充它:

Python 2.7.3 (default, Jun 22 2015, 19:43:34)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from src.catalog.models import Tree
>>> Tree.objects.create(name='1', slug='2')
<Tree: 1>
>>> Tree.objects.all()
[<Tree: 1>]

我编写了一个使用旧模型信息填充Tree模型的迁移:

def propagate_tree(app_registry, schema_editor):
    Category = app_registry.get_model('catalog', 'Category')
    Tree = app_registry.get_model('catalog', 'Tree')

    for category in Category.objects.all():
        parent = Tree.objects.create(name=category.title, slug=category.slug)

        for group in category.group_set.all():
            Tree.objects.create(parent=parent, name=group.title, slug=group.slug)

我收到以下错误:

django.db.utils.IntegrityError: null value in column "lft" violates not-null constraint

执行以下行:

parent = Tree.objects.create(name=category.title, slug=category.slug)

仍无法理解此错误的原因:(

2 个答案:

答案 0 :(得分:2)

我刚遇到同样的问题,原因是使用app_registry进行模型导入。 在迁移中替换它:

Tree = app_registry.get_model('catalog', 'Tree')

正常导入,就像在shell中一样。

from src.catalog.models import Tree

它应该像魅力一样工作。

但是,我不知道为什么第一个不起作用,因为就我而言,它是在迁移文件中导入模型的首选方式。

答案 1 :(得分:0)

您不应该在迁移中导入模型。使用建议的方式获取您的模型:

apps.get_model("app_name", "ModelClassName")

然后创建模型实例并在保存前将以下成员设置为 0:

lftrghtleveltree_id

为您的模型创建一个 post_migration 钩子并在那里重建 MPTT 树,例如

@receiver(post_migrate)
def rebuild_handler(sender, **kwargs):
    if sender.name == "your_app_name":
        YourModelClass.objects.rebuild()