3

django-mptt を使用して、記事を保存する見出しのセクションやサブセクションなどをモデル化しました。一部のセクションとセクションには子があり、他のセクションにはありません。例えば:

[Home]
 [News]
    [Politics][Crime][Policing]  etc 
 then [News] > [Politics]
                 [UKIP][Labour] etc

私はあなたがその考えを理解すると確信しています。Section モデルを作成しました

class Section(MPTTModel):
    name = models.CharField(max_length=50)
    parent = TreeForeignKey('self',null=True, blank=True, related_name='sub_sections')
    tree = SectionTreeManager()

そして、 Section.objects.all() をテンプレートに渡すことにより:-

<ul class="headernav" >

    {% recursetree sections %}

        <li>
            <a href="/section/{{node.name}}" >{{ node.name }}</a>

             {% if node.is_leaf_node %}
                <ul  class="headernav"> 
                    {{ children }}
                </ul>
            {% endif %}
           </li>
    {% endrecursetree %}
</ul>

すべてのノードを表示できます。私がやりたいことは、現在のURL、つまり/section/Newsに基づいて、現在のレベルのすべての兄弟、前のレベルのすべての祖先、および下のレベルのすべての関連する子孫を取得することです。ニュースを選択すると

[home][**News**][World][Sports][Culture] <- Level 0

[Politics][Crime][Education] <- Children on Level 1

これどうやってするの?どんな助けでも大歓迎です。私は Django を学んでいるので、明らかな場合は事前にお詫び申し上げます。

4

1 に答える 1

6

django-page-cmsは、を使用してこのタイプの問題を解決しdjango-mpttたので、そこで行われている方法を確認することをお勧めします。

具体的には、ツリーメニューをレンダリングするためのテンプレートは、と呼ばれるカスタムテンプレートタグを介して再帰的に含まれpages_dynamic_tree_menuます。

これは複雑に聞こえるので(カスタムta-whaaa!)、もう少し詳しく説明します。

Pageinはdjango-page-cmsクラスとほぼ同じと見なすことができますSection

ページの99%で共有される基本テンプレートにdjango-page-cms 、次のスニペットを挿入します

<ul>
{% for page in pages_navigation %}
    {% pages_dynamic_tree_menu page %}
{% endfor %}
</ul>

pages_navigation コンテキストプロセッサ(djangoプロジェクトのすべてのビューのテンプレートコンテキストにアイテムを追加する方法) によって設定され、トップレベルのページ(つまり、親のないページ)が含まれます。

タグは次のpages_dynamic_tree_menuように定義および登録されます。

def pages_dynamic_tree_menu(context, page, url='/'):
    """
    Render a "dynamic" tree menu, with all nodes expanded which are either
    ancestors or the current page itself.

    Override ``pages/dynamic_tree_menu.html`` if you want to change the
    design.

    :param page: the current page
    :param url: not used anymore
    """
    lang = context.get('lang', pages_settings.PAGE_DEFAULT_LANGUAGE)
    page = get_page_from_string_or_id(page, lang)
    children = None
    if page and 'current_page' in context:
        current_page = context['current_page']
        # if this node is expanded, we also have to render its children
        # a node is expanded if it is the current node or one of its ancestors
        if(page.tree_id == current_page.tree_id and
            page.lft <= current_page.lft and
            page.rght >= current_page.rght):
            children = page.get_children_for_frontend()
    context.update({'children': children, 'page': page})
    return context
    pages_dynamic_tree_menu = register.inclusion_tag(
        'pages/dynamic_tree_menu.html',
        takes_context=True
    )(pages_dynamic_tree_menu)

pageその要点は、とchildren変数を設定すること です。

魔法はifステートメントにあり、ページが現在のものである場合(current_pageテンプレート変数はdjango-page-cmsをレンダリングするビューによって設定されるPage)、またはページが祖先である場合にのみ子が表示されるようにします。lftrght属性はによって提供されdjango-mptt、このMPTTの2つのプロパティは、親ツリーノードの左の値が子ノードの左の値よりも小さくなり、親ノードの右の値がの右の値よりも大きくなることです。その子ノード。SQLのツリーの記事から下の画像を見ると視覚的に確認できます。

MPTTの写真

未公開のオブジェクトを非表示にするためのフィルタリングを使用して呼び出すget_children_for_frontend()メソッド。特別なことは何もありません。PageMPTTModel.getChildren()Page

次に、タグはテンプレートと同等のタグを実行します。これにより、タグが再度呼び出され、すべてが繰り返されます。{% include %}pages/dynamic_tree_menu.htmlpages_dynamic_tree_menu

{% load pages_tags cache %}
{% if page.calculated_status %}
<li {% ifequal page current_page %}class="selected"{% endifequal %}>
<a href="{% show_absolute_url page %}">{% show_content page "title" %}</a>
{% if children %}
    <ul>{% for child in children %}{% pages_dynamic_tree_menu child url %}{% endfor %}</ul>
{% endif %}
</li>
{% endif %}

したがって、同様の設定を定義し(テンプレートに最上位のセクションと現在のセクションを提供し、「包括的」テンプレートタグとタグに一致するテンプレートを定義する)、スタイルを適用すると、このアプローチを使用して達成できるはずです。あなたの目標。

于 2012-10-11T05:56:44.873 に答える