从django-cms CMSAttachMenu获取视图pk

时间:2012-12-15 19:43:13

标签: python django django-cms

我在django-cms中有一个自定义应用程序,需要将子菜单附加到我的应用程序。 我已经按照我发现的指南和示例执行此操作(请参阅Brandon在此处提供的投资组合示例:custom views within Djangocms?),并设法启动并运行子菜单。

通过扩展上面提供的例子;如果此组合应用程序在此处显示,包含少量不同视图(创建视图,详细视图以及可能还有其他几个相关视图),该怎么办?如果我需要构建一个子菜单来保存这个小应用程序中与用户导航相关的选项,该怎么办?如果导航应根据视图中的选定内容呈现选择(仅在选择或类似的投资组合时为“编辑”),该怎么办? 子菜单必须知道选择了什么投资组合,对吧?或者至少实际上选择了一个投资组合并在视野中。

我如何转移到CMSAttachMenu的实现我的观点已经知道了什么?就我而言,我正在实现一个处理聚会或“事件”的应用程序。下面的示例不起作用,因为事件对象显然没有在请求中注册,但它说明了我想要的内容:

# menu.py
from django.core.urlresolvers import reverse
from menus.base import NavigationNode
from menus.menu_pool import menu_pool
from cms.menu_bases import CMSAttachMenu
from App.apps.event.models import Event
from django.utils.translation import ugettext_lazy as _
import logging

logger = logging.getLogger('instant.event')


class EventMenu(CMSAttachMenu):

    name = _("Event Sub-Menu")

    def get_nodes(self, request):
        nodes = []
        nodes.append(NavigationNode(_('Create new events'), reverse("admin:event_event_add"), 1 + len(nodes), 0))

        if hasattr(request, 'event'):
            if request.event.is_registered_to_event(request.user):
                nodes.append(NavigationNode(_('Unregister from this event'), reverse("unregister_from_event"), 1 + len(nodes), 0))
            else:
                nodes.append(NavigationNode(_('Register to participate in this event'), reverse("unregister_from_event"), 1 + len(nodes), 0))

        if request.user.is_superuser():
            nodes.append(NavigationNode(_('Register other participant to this event'), reverse("register_admin", args=(request.event.id)), 1 + len(nodes), 0))

        nodes.append(NavigationNode(_('Back to list of events'), reverse("events"), 1 + len(nodes), 0))
    return nodes

menu_pool.register_menu(EventMenu)

1 个答案:

答案 0 :(得分:1)

这是一个很难的,但以下将解决它(仅显示相关部分):

<强> cms_app.py

from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
from django.utils.translation import ugettext_lazy as _

class EventsApphook(CMSApp):
    name = _("Event")
    urls = ["App.apps.event.urls"]
apphook_pool.register(EventsApphook)

<强> menu.py

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

menuNodes = []

class EventMenu(CMSAttachMenu):
    name = _("Event Sub-Menu")
    def get_nodes(self, request):
        return menuNodes
menu_pool.register_menu(EventMenu)

def add_menu_node(text, url):
    # only add a given url once
    if len(list(n for n in menuNodes if n.url == url)) == 0:
        menuNodes.append(NavigationNode(text, url, 1 + len(menuNodes), 0))
        menu_pool.clear()

<强> views.py

from django.views.generic.detail import DetailView
from django.core.urlresolvers import reverse
from django.utils.translation import ugettext_lazy as _
from App.apps.event.menu import add_menu_node
from App.apps.event.models import Event

class EventMenuMixin(object):
    def get_context_data(self, **kwargs):
        context = super(EventMenuMixin, self).get_context_data(**kwargs)
        member = self.request.user

        if 'pk' in self.kwargs.keys():
            event = Event.objects.get(id=self.kwargs['pk'])
            if event.is_registered_to_event(member):
                add_menu_node(_('Unregister from this event'), reverse("unregister_from_event"))
            else:
                add_menu_node(_('Register to participate in this event'), reverse("register_to_event", args=(self.kwargs['pk'])))

        add_menu_node(_("Create new events"), reverse("admin:event_event_add"))
        return context

class EventDetailView(EventMenuMixin, DetailView):
    model = Event
    template_name = 'event/event_detail.html'
    context_object_name = 'event'

我希望这会帮助其他人和我一样陷入困境。

相关问题