在现有菜单中插入新的子菜单项

mko*_*nen 3 django django-cms

我正在开发一个项目,我需要能够以编程方式将大量基于应用程序模型的项目注入到现有的基于CMS的菜单中.我已经开始使用此处的代码来修改菜单:http://docs.django-cms.org/en/2.3.3/extending_cms/app_integration.html.

编辑:更多细节

我的客户希望我将应用程序模型对象附加到CMS菜单,以便它们是菜单中现有CMS页面的子项.我目前有一个完全黑客的地方,要求我在CMS中制作假页面,它们是所需菜单项的子项,与应用程序模型对象具有相同的名称,然后,我安装了一个如下修饰符:

class SportsMenuModifier(Modifier):
  def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb):
    if post_cut:
      return nodes

    for node in nodes:
      if node.title == "Baseball":
        node.url = "/sports/baseball"
      elif node.title == "Football":
        node.url = "/sports/Football"
      elif node.title == "Bowling":
        node.url = "/sports/bowling"
      elif node.title == "Golf":
        node.url = "/sports/golf"

    return nodes

menu_pool.register_modifier(SportsMenuModifier)
Run Code Online (Sandbox Code Playgroud)

这有很多错误,我不知道从哪里开始,但我将使用这个非详尽的列表来突出一些最基本的问题:

  • 需要存在"假"CMS页面
  • 可笑地依赖于应用程序运动对象和虚假页面的命名
  • 无法检测客户何时创建新的运动物体
  • 每个参与者都很困惑

我希望我能做的就是这样(不会工作):

在models.py中

from django.db import models
from cms.models.pagemodel import Page

class Sport(models.Model):
  name = models.CharField(...)
  parent = modes.ForeignKey(Page, ...)
  ...
Run Code Online (Sandbox Code Playgroud)

在menu.py中

class SportsMenu(Menu):
  def get_nodes(self, request):
    nodes = []

    for sport in Sports.objects.filter(...).order_by('order'):
      node = NavigationNode(
        _(sport.name),
        sport.get_absolute_url(),
        sport.pk,
        sport.parent.pk
      )
      nodes.append(node)

    return nodes

menu_pool.register_menu(SportsMenu)
Run Code Online (Sandbox Code Playgroud)

我不确定我是否可以继续使用这种方法,因为:

  1. 我不知道如何获取给定页面的menu.namespace

  2. 即使我将命名空间硬编码为"CMSMenu"(我在某处读到这就是它),这仍然无法实现.

那么,我们如何将基于应用程序模型的对象作为子项附加到现有的基于CMS页面的菜单项?

mko*_*nen 6

对此的答案是我应该一直在使用(和使用AM)Attach Menus,遗憾的是,这里的文档很难记录:https://django-cms.readthedocs.org/en/latest/extending_cms/app_integration.html#附加菜单.

另外,当我按照这些说明操作时,我不小心从menus.base导入CMSAttachMenu,而不是从cms.menu_bases导入,这不会导致任何错误,但也没有做任何事情,因此,调试相当困难= /

以下是一些工作代码,以防将来帮助任何人:

在models.py中

from django.db import models

class Sport(models.Model):
  name = models.CharField(max_length=64, blank=True)
  slug = models.SlugField(blank=True)

  def __unicode__(self):
    return self.name

  def get_absolute_url(self):
    return "/sports/" + self.slug
Run Code Online (Sandbox Code Playgroud)

在menu.py中

from cms.menu_bases import CMSAttachMenu
from django.utils.translation import ugettext_lazy as _
from menus.base import NavigationNode
from menus.menu_pool import menu_pool

from apps.theproject.models import Sport


class SportSubMenu(CMSAttachMenu):

  name = _("Sports Sub-Menu")

  def get_nodes(self, request):

    nodes = []
    for sport in Sport.objects.order_by('order'):
      node = NavigationNode(
        sport.name,
        sport.get_absolute_url(),
        sport.pk
      )
      nodes.append(node)

    return nodes

menu_pool.register_menu(SportSubMenu)
Run Code Online (Sandbox Code Playgroud)

将这两个文件就地后,重新启动该服务.在Django-CMS中,导航到您希望各种Sports对象的菜单项在菜单中显示为子菜单项的页面.

在"高级设置"部分(通常是已折叠)中,您将看到一个新选项"附加菜单",选择新项目"体育子菜单",您将开始营业.