0

django-cms内にカスタムアプリがあり、アプリにサブメニューを添付する必要があります。私はこれを行うために見つけたガイドと例に従い(ここでブランドンによって与えられたポートフォリオの例を参照してください:Djangocms内のカスタムビュー?)、サブメニューを起動して実行することができました。

上記の例を拡張することにより、このポートフォリオアプリがここに表示され、少数の異なるビュー(作成ビュー、詳細ビュー、およびおそらく他のいくつかの関連ビュー)で構成されている場合はどうなりますか。この小さなアプリでユーザーナビゲーションに関連する選択肢を保持するサブメニューを作成する必要がある場合はどうなりますか。また、ナビゲーションがビューで選択されたコンテンツに基づいて選択肢を表示する必要がある場合はどうなりますか(ポートフォリオが選択されているか類似している場合にのみ「編集」)。サブメニューは、どのポートフォリオが選択されたかを知る必要がありますよね?または、少なくともポートフォリオが実際に選択されて表示されていること。

ビューがすでに知っていることをCMSAttachMenuの実装に転送するにはどうすればよいですか?私の場合、交流会や「イベント」を扱うアプリを実装しています。以下の例は、Eventオブジェクトが明らかにリクエストに登録されていないため機能しませんが、私が望むものを示しています。

# 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)
4

1 に答える 1

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()

ビュー.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'

これが私と同じ苦境にある他の人に役立つことを願っています。

于 2012-12-17T21:45:24.463 に答える