【问题标题】:Django queryset with recursive many-to-many and result displayed具有递归多对多和结果显示的 Django 查询集
【发布时间】:2026-01-10 20:05:02
【问题描述】:

我想获得您的帮助,以便通过处理多对多字段并显示结果来找到我的问题的解决方案。

预期结果:

我的应用程序中有一个内容版本列表(例如:第 8 版、第 9 版、第 10 版...),对于每个版本,我都有一个带有颠覆的集合列表(toto 9.8、toto 9.9、toto 9.10 , toto 10.0, ...)。

我正在尝试根据内容版本显示包含选项卡的动态导航栏。每个选项卡都包含子版本列表。

标签 9th Edition 包含 9.8、9.9、9.10、...

标签 10th Edition 包含 10.0, ...

---------

我的模型

我有一个模型文件,其中有:

class NavbarMenuSettings(models.Model):
    """ A class to manage navbar menu of the application """
    collection = models.ManyToManyField('publication.Collection', related_name='collection_list', symmetrical=False)
    application = models.ForeignKey('publication.WebApplication', verbose_name=_('application'), related_name='application', on_delete=models.CASCADE)
    title = models.CharField(max_length=30, verbose_name=_('title'), default=('Xth Edition (Current)'))
    order = models.PositiveSmallIntegerField(default=1, verbose_name=_('menu order'), blank=True, null=False)
    display = models.BooleanField(verbose_name=_('Display menu'), default=True)

    class Meta:
        verbose_name = _('menu setting')
        verbose_name_plural = _('menu settings')

我有一个 menu.py 文件可以用来处理我的导航栏:

def list_of_edition():
    """ Return list of editions """
    instance = NavbarMenuSettings.objects.filter(display=True).order_by('order')
    return instance

edition_children = ()
for instance in list_of_edition():
    edition_children += MenuItem(instance.collection.all(), reverse('home'), weight=150, separator=False),


for instance in list_of_edition():
    Menu.add_item('edition', MenuItem(instance.title, '#', children=edition_children))

我正在尝试使其具有动态性。它为每个显示的 NavbarMenuSettings 对象创建一个新选项卡。但是在每个选项卡中,我都会获得所有子版本的列表,或者我想为每个选项卡显示仅关联的子版本。

我的测试:

如果我写这个测试:

for element in list_of_edition():
    print(element.title)
    print(element.collection.all())

它显示:

10th Edition (Current)
<QuerySet [<Collection: 10.0 lite>]>
9th Edition
<QuerySet [<Collection: 9.8 lite>, <Collection: 9.9 lite>, <Collection: 9.10 lite>]>

但是我如何处理我的菜单以显示每个选项卡版本以及相关的子版本列表?

我在这一步被阻止了。

谢谢

【问题讨论】:

  • 你想在模板中显示这个是吗?
  • @gd8 你是对的,但目前我还没有克服显示具有良好颠覆性的标签。
  • 在公共收藏模型中有9.1、9.2版本吗?
  • 非强制性,第 9 版包含从 9.X 开始的版本,第 10 版包含从 10.X 开始的版本。但它可能是 Y.1、Y.12、颠覆。我没有克服的是将subversions分组到好版本并显示在每个版本选项卡上,只有subversions关联。
  • 我的意思是?你怎么知道 9.1、9.2、9.3 是 9 的颠覆?它们是如何在数据库级别创建的?你有 NavbarMenuSettings 模型,但是 Collection 模型呢?它们是用来做什么的?

标签: python django django-models django-views django-orm


【解决方案1】:
from collections import OrderedDict
od = OrderedDict()
for version in list_of_edition():
    #print(element.title)
    #print(element.collection.all())
    od.setdefault((version.pk, version.title) []).extend([(subversion.pk, subversion.title) for subversion in version.collection.all()])
print(od)

试试这个代码。让我们知道会出现什么问题。

【讨论】:

  • 它显示OrderedDict([(2, [58464]), (1, [21928, 29235, 36542])]) 似乎将subversions id分组到正确的版本id。现在,我们必须看看如何通过添加标题来重写菜单选项卡。
  • 我更新了答案...如果您的问题已解决,请告诉我。
  • 结果符合预期,但我如何将您的代码集成到Menu.add_itemMenuItem 以显示我的导航栏?
  • 这个案例标记为已解决,,,你到底是什么意思?你想在你的 html 模板中显示这个吗?
  • 我不知道你的Menu和MenuItem是什么,,,我会告诉你你需要什么。在您的视图函数中渲染模板并传递您的变量(od)并使用 django 模板语言迭代模板中的 od 变量。