Manipulating Menus#

Django Flex Menus builds on the powerful anytree library, which provides a comprehensive set of tools for working with tree structures. This gives you access to a rich API for manipulating menu hierarchies.

Basic Capabilities from anytree#

The anytree library provides fundamental tree operations that work seamlessly with Django Flex Menus:

Tree Traversal#

from anytree import PreOrderIter, PostOrderIter

# Iterate through all nodes in pre-order (parent first, then children)
for item in PreOrderIter(menu):
    print(f"Item: {item.name}, Depth: {item.depth}")

# Iterate through all nodes in post-order (children first, then parent)  
for item in PostOrderIter(menu):
    print(f"Item: {item.name}")

Tree Information#

# Get all ancestors of a node
ancestors = item.ancestors

# Get all descendants
descendants = item.descendants  

# Get siblings
siblings = item.siblings

# Check if node is root
is_root = item.is_root

# Check if node is leaf
is_leaf = item.is_leaf

# Get path from root to node
path = item.path

Additional Methods from Django Flex Menus#

Django Flex Menus extends anytree with menu-specific functionality:

Adding Children#

parent = MenuItem(name="parent")

# Append
parent.append(MenuItem(name="child1", url="/1/"))

# Extend multiple
parent.extend([
    MenuItem(name="child2", url="/2/"),
    MenuItem(name="child3", url="/3/"),
])

Accessing Children#

# Get by name
item = menu.get("child_name")

# Bracket notation
item = menu["child_name"]

# Iterate
for child in menu.children:
    print(child.name)

Insert After#

parent.insert_after(
    "existing_child",
    MenuItem(name="new_child", url="/new/"),
)

Remove#

# Remove child by name
removed = parent.pop("child_name")

# Remove self from parent
item.pop()

Practical Examples#

Dynamic Menu Building#

# Build a menu dynamically based on user permissions
admin_menu = Menu("admin_menu")

if user.has_perm('auth.view_user'):
    admin_menu.append(MenuItem(name="users", view_name="admin:users"))

if user.has_perm('blog.view_post'):
    admin_menu.append(MenuItem(name="posts", view_name="admin:posts"))

# Group related items
if user.is_superuser:
    system_menu = MenuItem(name="system", children=[
        MenuItem(name="settings", view_name="admin:settings"),
        MenuItem(name="logs", view_name="admin:logs"),
    ])
    admin_menu.append(system_menu)

Conditional Menu Items#

# Add items based on conditions
for category in user_categories:
    category_item = MenuItem(
        name=f"category_{category.id}",
        view_name="category:detail"
    )
    products_menu.append(category_item)

Further Reading#

For more advanced tree operations, consult the anytree documentation. All anytree features are available when working with Django Flex Menus.