【问题标题】:DjangoCMS NavigationNode - custom nodeDjangoCMS NavigationNode - 自定义节点
【发布时间】:2016-12-10 07:45:02
【问题描述】:

DjangoCMS 中的默认 NavigationNode 的节点为:

  • 孩子们
  • 标题
  • get_menu_title
  • get_attribute

在相同的上下文中,我想添加我的自定义节点,称为:category_name,它将返回字符串“某物”(仅用于测试目的)。

official documentation 之后,没有找到任何可以帮助我解决问题的方法。在查找默认 NavigationNode 的声明时,出现如下代码:

从 menus.base 导入 NavigationNode

base.py 文件:

class NavigationNode(object):

    def __init__(self, title, url, id, parent_id=None, parent_namespace=None,
                 attr=None, visible=True):
        self.children = []  # do not touch
        self.parent = None  # do not touch, code depends on this
        self.namespace = None  # TODO: Assert why we need this and above
        self.title = title
        self.url = url
        self.id = id
        self.parent_id = parent_id
        self.parent_namespace = parent_namespace
        self.visible = visible
        self.attr = attr or {} # To avoid declaring a dict in defaults...

    def __repr__(self):
        return "<Navigation Node: %s>" % smart_str(self.title)

    def get_menu_title(self):
        return self.title

    def get_absolute_url(self):
        return self.url

    def get_attribute(self, name):
        return self.attr.get(name, None)

    def get_descendants(self):
        return sum(([node] + node.get_descendants() for node in self.children), [])

    def get_ancestors(self):
        if getattr(self, 'parent', None):
            return [self.parent] + self.parent.get_ancestors()
        else:
            return []

如果我在此处添加名为 category_name 的自定义节点,它将起作用。但是修改基础文件并不是一个聪明的解决方案。

所以我的问题是:

如何在 base.py 之外添加我的自定义节点? IE。如果我想添加 它在我的应用程序 models.py 文件中。这甚至可能吗?

【问题讨论】:

    标签: python django django-cms


    【解决方案1】:

    我终于找到了解决办法。答案是:是的!有可能的。

    正如文档中所述,您可以使用 modify() 方法。

    但这对我不起作用,因为我对 node.attr["changed_by"] 感到困惑。在模板中,我想使用这样的东西:{{ child.category_name }} 但很明显,我修改错了。

    正确的做法是这样的:

    from menus.base import Modifier
    from menus.menu_pool import menu_pool
    
    from cms.models import Page
    
    class MyMode(Modifier):
        """
    
        """
        def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb):
            # if the menu is not yet cut, don't do anything
            if post_cut:
                return nodes
            # otherwise loop over the nodes
            for node in nodes:
                # does this node represent a Page?
                if node.attr["is_page"]:
                    # if so, put its changed_by attribute on the node
                    node.category_name = "Some category name here"
            return nodes
    
    menu_pool.register_modifier(MyMode)
    

    现在,在 menu.html 中,你可以使用 child.category_name,它会输出字符串“Some category name here”

    {% load i18n menu_tags cache %}
    
    {% for child in children %}
    <li>
        {% if child.children %}
        <a href="{{ child.get_absolute_url }}">
            {{ child.get_menu_title }} <span class="caret"></span>
        </a>
        <ul class="menu-vertical">
            {% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
        </ul>
        {% else %}
            <a class1="{{ child.get_absolute_url }}" href="{{ child.get_absolute_url }}">
                {% if child.category_name %}
                    <b>{{ child.category }}</b>
                {% endif %}
                {{ child.get_menu_title }}
            </a>
        {% endif %}
    </li>
    {% if class and forloop.last and not forloop.parentloop %}{% endif %}
    {% endfor %}
    

    最后,经过数小时的尝试,我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 2011-08-23
      • 2015-01-23
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      • 2021-07-25
      • 2015-10-04
      • 2015-10-17
      • 1970-01-01
      相关资源
      最近更新 更多