【问题标题】:Django-MPTT leaf nodes of multiple types多种类型的Django-MPTT叶节点
【发布时间】:2012-06-19 19:59:58
【问题描述】:

我正在开发一个分层应用程序,其中叶节点可以是不同模型的实例。我不知道如何使它与 django-mptt 应用程序一起工作。在那个应用程序中这甚至可能吗?如果是,我做错了什么?如果没有,有什么我想做的吗?

以下是模型的基本结构:

class FolderItemBase(MPTTModel):
    order = models.PositiveIntegerField()

    class Meta:
        abstract = True

    class MPTTMeta:
        parent_attr = 'folder'
        order_insertion_by = ['order']

class Folder(FolderItemBase):
    folder = TreeForeignKey('Folder', related_name='folders', blank=True, null=True)
    ...

class Image(FolderItemBase):
    folder = TreeForeignKey('Gallery', related_name='images') # cannot be null since leaf has to be inside of a folder
    ...

当我尝试执行以下操作时,我只能获得文件夹子项,而没有图像。当我尝试获取图像的祖先时也是如此

>>> folder1 = Folder.objects.create(title='Folder 1', order=0)
>>> folder2 = Folder(title='Folder 2', order=0)
>>> folder2.insert_at(folder1, save=True)
>>> image = Image(...)
>>> image.insert_at(folder1, save=True)
>>> folder1.get_children()
[<Folder: Folder 2>]
>>> image.get_ancestores()
[]

这就是所有这些东西在数据库中的存储方式:

Folder table
----------------
+----+-------+-----+------+---------+-------+-----------+----------+
| ID | order | lft | rght | tree_id | level | folder_id | title    |
+----+-------+-----+------+---------+-------+-----------+----------+
| 1  | 0     | 1   | 4    | 1       | 0     |           | Folder 1 |
+----+-------+-----+------+---------+-------+-----------+----------+
| 2  | 0     | 2   | 3    | 1       | 1     | 1         | Folder 2 |
+----+-------+-----+------+---------+-------+-----------+----------+

Images Table
------------
+----+-------+-----+------+---------+-------+-----------+
| ID | order | lft | rght | tree_id | level | folder_id |
+----+-------+-----+------+---------+-------+-----------+
| 1  | 1     | 2   | 3    | 1       | 1     | 1         |
+----+-------+-----+------+---------+-------+-----------+

如您所见,它计算了图像的级别编号和正确的(至少看起来是)左右编号,但是它不会更新文件夹表中的任何内容,因此当您尝试进行查询,没有选择任何内容。

任何指针表示赞赏。谢谢。

【问题讨论】:

    标签: django hierarchical-data django-mptt


    【解决方案1】:

    AFAIK,这是不可能的; django-mptt 背负着 Django 的 QuerySet,它只适用于一种类型的东西。您可以使用 contenttypes 框架将“真实”项目与 FolderItem 之类的东西相关联,这仅用于层次结构,例如

    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes import generic
    
    class FolderItem(MPTTModel):
        folder = TreeForeignKey('Folder', related_name='folders', blank=True, null=True
        order = models.PositiveIntegerField()
        content_type = models.ForeignKey(ContentType)
        object_id = models.PositiveIntegerField()
        content_object = generic.GenericForeignKey('content_type', 'object_id')
    
        class Meta:
            abstract = True
    
        class MPTTMeta:
            parent_attr = 'folder'
            order_insertion_by = ['order']
    

    然后,当您使用 django-mptt 管理器方法等时,您将返回一个 FolderItems 的查询集,并且您可以在迭代时访问每个 Folder/Image集合,通过通用外键。

    但是,请注意,这在数据库查询方面可能会很昂贵,因为每次访问通用外键时,都必须发出新的查询。

    【讨论】:

      猜你喜欢
      • 2012-06-07
      • 1970-01-01
      • 2017-07-29
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多