[REAL Python – Django] – “Django – Category & Post & Slug & URL 연동(2)”
[REAL Python – Django] – “Django – Category & Post & Slug & URL 연동(2)”
2022/05/05 7:35 PM
Total Views: 838Daily Views: 8

모든 URL에 대한 views.py 작성
from django.db.models import Q
from django.views.generic import ListView, DetailView
from django.http import Http404
from .models import Post, Category
class BasePostListView(ListView):
    '''
    /blog/ 로 들어오면 데이터베이스에 존재하는 모든 게시물이 표시되어야 함
    템플릿의 맨 처음에 "All Posts"
    '''
    model = Post
    ordering = '-pk'
    paginate_by = 9
    template_name = 'blog/base_post_list.html'
class PostByFirstCategoryListView(BasePostListView):
    # 한 포스트의 카테고리의 부모 카테고리의 부모 카테고리(할아버지 카테고리) 가 존재한다 -> 해당 포스트의 할아버지 카테고리 == 1차 카테고리가 됨
    # 3차 카테고리에만 글을 쓸 수 있도록 할 것이므로, 포스트의->카테고리의->부모카테고리의->부모카테고리 == URL 인자인 포스트들 뽑아와야 함
    def get_queryset(self):
        first_category_from_url = self.kwargs['first_category_slug']
        selected_post_list = Post.objects.filter(
            Q(category__parent__parent__name=first_category_from_url) | Q(
                category__parent__parent__slug=first_category_from_url)
            # URL 인자 == 할아버지 카테고리이거나 URL인자 == 할아버지 카테고리의 slug인 포스트들을 가져옴.
        ).distinct()  # 중복 제거
        return selected_post_list
class PostBySecondCategoryListView(BasePostListView):
    # 부모 카테고리이름==URL인자 or 부모카테고리의 슬러그==URL인자 인 포스트들 뽑아오기.
    def get_queryset(self):
        second_category_from_url = self.kwargs['second_category_slug']
        selected_post_list = Post.objects.filter(
            Q(category__parent__slug=second_category_from_url) | Q(category__parent__name=second_category_from_url)
        ).distinct()  # 중복 제거
        return selected_post_list
class PostByThirdCategoryListView(BasePostListView):
    def get_queryset(self):
        third_category_from_url = self.kwargs['third_category_slug']
        selected_post_list = Post.objects.filter(
            Q(category__slug=third_category_from_url) | Q(category__name=third_category_from_url)
        ).distinct()  # 중복 제거
        return selected_post_list
class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/post_detail.html'
현재의 코드를 붙여놓습니다.
모델에서 get_absolute_url 메서드 정의하기
아래는 카테고리 모델의 get_absolute_url 메서드입니다.
    def get_absolute_url(self):
        try:
            if self.parent.parent: # 카테고리의 할아버지 카테고리가 존재한다면,
                return f'/blog/{self.parent.parent.slug}/{self.parent.slug}/{self.slug}/'
            elif self.parent: # 부모 카테고리만 존재한다면,
                return f'/blog/{self.parent.slug}/{self.slug}/'
        except AttributeError:
            return f'/blog/{self.slug}/'
아래는 포스트 모델의 get_absolute_url 메서드입니다.
    def get_absoulute_url(self):
        return f'/blog/{self.category.parent.parent}/{self.category.parent}/{self.category}/{self.pk}/'
위처럼 코드를 작성하면 포스트는 다음의 URL을 가지게 됩니다!

발생한 문제 : 카테고리 드롭다운 구현 중 빈 리스트가 생성됨

                {# ----------categories---------- #}
                <li class="dropdown"><a href="/blog/"><span>Categories</span><i
                        class="bi bi-chevron-down dropdown-indicator"></i></a>
                    {# ----------categories dropdown---------- #}
                    <ul>
                        {% recursetree categories_list %}
                            <li class="dropdown">
                                <a href="{{ node.get_absolute_url }}">
                                    <span>{{ node.name }}</span>
                                    {% if not node.is_leaf_node %}
                                        <i class="bi bi-chevron-down dropdown-indicator"></i>
                                    {% endif %}
                                </a>
                                {% if not node.is_leaf_node %} {# 자식 카테고리가 존재한다면 #}
                                    <ul>
                                        <li class="dropdown"><a
                                                href="{{ children.get_absolute_url }}" >{{ children }}</a></li>
                                        <li><a>hello</a></li>
                                    </ul>
                                {% endif %}
                            </li>
                        {% endrecursetree %}
                    </ul>
                    {# ----------categories dropdown---------- #}
                </li>
                {# ----------categories---------- #}
문제가 발생한 코드인데…
                {# ----------categories---------- #}
                <li class="dropdown"><a href="/blog/"><span>Categories</span><i
                        class="bi bi-chevron-down dropdown-indicator"></i></a>
                    {# ----------categories dropdown---------- #}
                    <ul>
                        {% recursetree categories_list %}
                            <li class="dropdown">
                                <a href="{{ node.get_absolute_url }}">
                                    <span>{{ node.name }}</span>
                                    {% if not node.is_leaf_node %}
                                        <i class="bi bi-chevron-down dropdown-indicator"></i>
                                    {% endif %}
                                </a>
                                {% if not node.is_leaf_node %}
                                    <ul>
                                        <span>{{ children }}</span> {# <li>태그를 로드해 줌. #}
                                    </ul>
                                {% endif %}
                            </li>
                        {% endrecursetree %}
                    </ul>
                    {# ----------categories dropdown---------- #}
                </li>
                {# ----------categories---------- #}
이렇게 수정하니 정상 작동합니다. 혹시 저와 같이 드롭다운 메뉴(부트스트랩 템플릿을 이용했습니다.) 를 구현하실 분들은 참고!


