【问题标题】:Django CMS Multi-Level Dropdown MenuDjango CMS 多级下拉菜单
【发布时间】:2015-01-14 13:01:59
【问题描述】:

我对 Django CMS 有点陌生,我尽量避免问,但这让我发疯。 我制作了一个带有主题和类别模型的 Wiki 应用程序。我将它连接到我的 CMS 上的站点并将其添加到我的菜单中。现在我希望能够在我的菜单上显示所有顶级类别、它们的子类别和主题以及这些的子类别等等。

Menu/Navigation should look like this:

Wiki
    Category1
        Category1.1
            Topic
        Category1.2
        Topic
    Category2
        Topic
    Category3
        ...

Right now i can only show the Top categories:

Wiki
    Category1
    Category2
    Category3

我已经创建了一个 menu.py 来在我的 Wiki(您在上面看到的那个)上获取自定义子菜单:

menu.py

class WikiSubMenu(CMSAttachMenu):
    name = _("Wiki Sub-Menu")

    def get_nodes(self, request):
        nodes = []
        categories = Category.objects.filter(parent_id__isnull=True)

        for c in categories:
            node = NavigationNode(
                mark_safe(c.name),
                c.get_absolute_url(),
                c.id,

            )

            nodes.append(node)

        return nodes

menu_pool.register_menu(WikiSubMenu)

我的类别模型:

class Category(models.Model):
    ''' Category model. '''
    name = models.CharField(max_length=100)
    slug = models.SlugField(unique=True)
    description = models.TextField(blank=True)
    parent = models.ForeignKey(
        'self',
        null=True,
        blank=True,
        related_name='children'
    )
    sort = models.IntegerField(default=0)

    class Meta:
        ordering = ['sort', 'name']

    def __unicode__(self):
        return self.name

    @models.permalink
    def get_absolute_url(self):
        return ('topics:categories_category_detail', (), {'slug': self.slug})

    def get_all_children(self):
        return Category.objects.filter(parent=self)

现在,是否可以为所有具有子项及其子项及其子项等的类别创建一个子子菜单?

感谢您的帮助,抱歉英语不好

-- 编辑:--

我刚刚发现:

docs.django-cms.org/en/3.0.6/extending_cms/app_integration.html#integration-modifiers

(删除直接链接以添加 2 个新链接,对此感到抱歉)

我认为这就是我要寻找的东西,我有点盲目,我没有找到它。如果成功,我会尝试并发布答案。

-- 编辑(再次):--

修改器对我不起作用,但我得到了一个完整的部分, 我再次阅读Docs,发现我可以给 NavigationNodes 一个可选的 attr 字典,我用 parent=c 填充所有类别,这样我就有了我需要的数据,然后我发现真的很好@987654322 @,这正是我想要的。所以到目前为止我的代码看起来像这样:

menu.py

class TopicsSubMenu(CMSAttachMenu):
    name = _("Wiki Sub-Menu")

    def get_nodes(self, request):
        nodes = []
        categories = Category.objects.filter(parent_id__isnull=True)

        for c in categories:
            node = NavigationNode(
                mark_safe(c.name),
                c.get_absolute_url(),
                c.pk,
                attr=dict(
                    subcategories=Category.objects.filter(parent=c),),
            )

            nodes.append(node)
        return nodes

还有我的模板:

menu.html

{% for child in children %}
    <li>
        {% if child.children %}

            <a class="dropdown-toggle" data-toggle="dropdown" href="#">
                {{ child.get_menu_title }}
                <span class="caret">
                </span>
            </a>
            <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
                {% for child in child.children %}
                    {% if child.attr.subcategories.count %}
                        <li class="dropdown-submenu">
                            <a tabindex="-1" href="#">{{ child.get_menu_title }}</a>
                            <ul class="dropdown-menu">
                                {% for subcategory in child.attr.subcategories %}
                                <li>
                                    <a tabindex="-1" href="{{ subcategory.get_absolute_url }}">{{ subcategory }}</a>
                                </li>
                                {% endfor %}
                            </ul>


                        </li>
                    {% else %}
                    <li><a href="{{child.get_absolute_url}}">{{ child.get_menu_title }}</li></a>
                    {% endif %}
                {% endfor %}

            </ul>
        {% else %}
            <a href="{{ child.get_absolute_url }}">
                <span>
                    {{ child.get_menu_title }}
                </span>
            </a>
        {% endif %}
    </li>

    {% if class and forloop.last and not forloop.parentloop %}
    {% endif %}


{% endfor %}

我的下一步是在方法中从模板中编写整个“for”循环,使用 while 循环或其他东西使其递归,并将结果作为答案发布。

我希望我能在这方面帮助别人:)

【问题讨论】:

    标签: recursion menu parent-child django-cms tree-structure


    【解决方案1】:

    哇!我终于做到了!

    base.html

    <div class="navbar-collapse collapse">
        <ul class="nav navbar-nav">
            {% show_menu 0 100 100 100 "menu.html" %}
        </ul>
    </div>
    

    menu.html:

    {% for child in children %}
        <li class="child{% if child.selected %} selected{% endif %}{% if child.ancestor %} ancestor{% endif %}{% if child.sibling %} sibling{% endif %}{% if child.descendant %} descendant{% endif %}{% if child.children %} dropdown{% endif %}">
    
            <a {% if child.children %}class="dropdown-toggle" data-toggle="dropdown"{% endif %} href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">
                <span>{{ child.get_menu_title }}</span>{% if child.children|length %}<span class="caret"></span>{% endif %}
            </a>
    
            {% if child.children %}
                <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
                    {% show_menu from_level to_level extra_inactive extra_active "dropdownmenu.html" "" "" child %}
                </ul>
            {% endif %}
    
        </li>
        {% if class and forloop.last and not forloop.parentloop %}{% endif %}
    
    {% endfor %}
    

    还有我的 dropdownmenu.html: (递归的东西从这里开始)

    {% load i18n menu_tags cache mptt_tags %}
    {% for child in children %}
        <li {% if child.children %}class="dropdown-submenu"{% else %} {% endif %}>
            <a tabindex="-1" href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">{{ child.get_menu_title }}</a>
            {% if child.children %}
                <ul class="dropdown-menu">
                    {% show_menu from_level to_level extra_inactive extra_active "dropdownmenu.html" "" "" child %}
                </ul>
            {% endif %}
    
        </li>
    {% endfor %}
    

    还有最重要的,menu.py:

    class TopicsSubMenu(CMSAttachMenu):
        name = _("Wiki Sub-Menu")
    
        def get_nodes(self, request):
            nodes = []
            categories = Category.objects.all()
    
            for c in categories:
                node = NavigationNode(
                    mark_safe(c.name),
                    c.get_absolute_url(),
                    c.pk
                )
                if c.parent:
                    node.parent_id = c.parent_id
                nodes.append(node)
    
            topics = Topic.objects.all().exclude(category__isnull=True)
            for t in topics:
                node = NavigationNode(
                    mark_safe(t.title),
                    t.get_absolute_url(),
                    t.pk,
                    t.category.all()[0].id,
                    parent_namespace="TopicsSubMenu"
                )
                nodes.append(node)
            return nodes
    
    menu_pool.register_menu(TopicsSubMenu)
    

    就是这样!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多