[Django Recipe] 디자인 부담을 덜어주는 django-adminlte3 – part 3

django-adminlte3 – part 3

django-adminlte3와 django-mptt로 사이드바 tree 메뉴 만들기

django-mptt 설치와 설정은 django-mptt로 tree구조 만들기(https://blog.boxcorea.com/wp/archives/2605)를 참고하면 된다.

관리자페이지에서 아래와같은 tree구조를 만들었고, 이것을 사이드바에 tree 구조로 보이도록 view를 만들어본다.

project/app/urls.py에 url을 등록한다.

urlpatterns = [
    path('category', CategoryView.as_view(), name='category'),
    path('test/', TestView.as_view(), name='test'),
]

project/app/views.py 에 아래와 같이 view를 만든다.

class CategoryView(View):
    template_name = 'chaser/category.html'

    def get(self, request):
        context = {
            'categories': Category.objects.all(),
        }
        return render(request, self.template_name, context)

이제, project/templates/adminlte/lib/_main_sidebar.html 을 아래처럼 수정한다.

{% extends 'adminlte/lib/_main_sidebar.html' %}

{% block user_panel %}
{% endblock %}

{% block form %}
{% endblock %}

{% block nav_links_ul %}
<nav class="mt-2">
    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
    {% block nav_links_outer %}
        <li class="nav-header">{% block nav_heading %}CATEGORY{% endblock nav_heading%}</li>
        {% block nav_links %}
            <li class="nav-item has-tree-view ">
                <a href="#" class="nav-link">
                    <i class="nav-icon fas fa-object-group"></i> <p>Parents</p>
                    <p><i class="right fas fa-angle-left"></i>
                    </p>
                </a>
                <ul class="nav nav-treeview menu-open">
                    <li class="nav-item">
                        <a href="#" class="nav-link">
                            <i class="nav-icon fas fa-circle"></i> child
                        </a>
                    </li>
                </ul>
            </li>

        {% endblock nav_links %}
    {% endblock nav_links_outer %}
    </ul>
</nav>
{% endblock nav_links_ul %}

이제, 아래처럼 사이드바 메뉴가 바뀐 것을 볼 수 있다.

다음으로, CategoryView에서 전달받은 값을 사이드바에 표현하도록 템플릿을 수정한다.
project/templates/index.html이 /project/templates/adminlte/lib/_main_sidebar.html를 include 하기때문에, _main_sidebar.html에 아래 내용을 넣으면 전체 템플릿에 적용된다.

{% extends 'adminlte/lib/_main_sidebar.html' %}
{% load mptt_tags %}

{% block user_panel %}
{% endblock %}

{% block form %}
{% endblock %}

{% block nav_links_ul %}
<nav class="mt-2">
    <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu" data-accordion="false">
    {% block nav_links_outer %}
        <li class="nav-header">{% block nav_heading %}MainMenu{% endblock nav_heading%}</li>
        {% block nav_links %}

        <li class="nav-item has-treeview ">
            <a href="#" class="nav-link"><i class="nav-icon fas fa-circle text-warning"></i><p>Category</p><p><i class="right fas fa-angle-left"></i></p></a>
            <ul class="nav nav-treeview">
            {% recursetree categories %}
                <li class="nav-item has-treeview">
                    <a href="#" class="nav-link"><i class="nav-icon nav-icon far fa-circle text-info"></i>{{node.name}}</a>
                {% if not node.is_leaf_node %}
                <ul class="nav nav-treeview">
                    {{ children }}
                </ul>
                {% endif %}
                </li>
            {% endrecursetree %}
            </ul>
        </li>
        {% endblock nav_links %}
    {% endblock nav_links_outer %}
    </ul>
</nav>
{% endblock nav_links_ul %}

이제, 아래 그림처럼 사이드바 메뉴에 Category가 적용된 것을 확인 할 수 있다.

사이드바 트리 확장 전

사이드바 트리메뉴 확장

하지만, 위의 그림에서는 상위 카테고리인지 하위카테고리인지 확인이 쉽지 않다. 이것은 MPTT에서 indent설정이 적용되지 않기때문에, mptt indent와 관계없다.
https://adminlte.io/docs/3.0/components/main-sidebar.html 문서를 참고하여, nav-child-indent 속성을 ul class에 추가하면 된다.
즉, 12번 줄을 다음과 같이 수정한다.

<ul class="nav nav-pills nav-sidebar nav-child-indent flex-column" data-widget="treeview" role="menu" data-accordion="false">

이제, 아래 그림처럼 좀 더 직관적인 tree 구조의 메뉴를 볼 수 있다.

이후에 http://localhost:8000/test 에 접속하면, 변수를 찾을 수 없다는 메시지를 볼 수 있다.

이것은 test.html 이 index.html 템플릿을 확장하는데, categories 변수를 전달받지 못해서 그렇다.
이 문제를 해결하기 위해, TestView 클래스가 CategoryView를 상속받도록 코드를 수정한다.
project/app/views.py

class CategoryView(View):
    template_name = 'index.html'
    category = Category.objects.all()

    def get(self, request):
        context = {
            'categories': self.category,
        }
        return render(request, self.template_name, context)


class TestView(CategoryView, TemplateView):
    template_name = 'chaser/test.html'

하지만, TestView는 의도와는 다르게 제대로 작동하지 않는다.
그래서, CategoryView와 동일하지만 템플릿만 다른 코드를 작성했다.

class TestView(View):
    template_name = 'chaser/test.html'
    category = Category.objects.all()

    def get(self, request):
        context = {
            'categories': self.category,
        }
        return render(request, self.template_name, context)

이제, 왼쪽의 메뉴와 본문이 모두 제대로 보인다.

현재시점에서 django-adminlte3 문서가 나오지 않아서 사용하기에 조금 어려운 면이 있지만, 디자인은 위의 adminlte3 문서를 참고하고 블럭은 https://github.com/d-demirci/django-adminlte3/tree/master/adminlte3/templates/adminlte/lib
의 파일들을 참고하여 사용하면 될 것이다.

답글 남기기

Your email address will not be published.