63 Django 글 태그 링크 검색기능 넣기

63.1 태그 검색 기능

모델에 tags 필드가 있고,
데이터가 위 그림과 같이 있습니다.

태그를 클릭하면 해당 태그들을 검색하고 pythonblog.co.kr/tags/ 에서 해당 태그의
글 목록이 보여지게 작업하였습니다.

63.2 재사용 가능한 뷰 만들기

pythonblog는 앱이 2개, 모델도 2개입니다.
- coding 폴더: python코딩/
- blog 폴더 : Django사이트만들기

2개의 모델이 tags 필드를 검색할 때 같이 사용 할 수 있도록
TagMinx class를 만들었습니다.

super()를 통해 model queryset을 가져오고
파라메터(q)로 like 검색하고 queryset을 return 합니다.

coding/views.py에서 TagListView 클래스를 만들고,
TagMinx 상속 받아 사용할 것입니다.

1
2
3
4
5
6
7
class TagMixin(object):
    def get_queryset(self):
        queryset = super().get_queryset()
        q = self.request.GET.get('q')       
        if q:
            return queryset.filter(tags__icontains=q)
        return queryset

63.3 TagListView 구현

TagListView에 TagMixin 상속 받으면 끝입니다.

pythonblog.co.kr는
좌측 메뉴/파라메터(q) 제목에 사용 /추가 filter조건이
필요하기 때문에 get_context_data를 오버라이딩 했습니다.

검색 결과 조건 절을 추가하기 위해 부모(super()/TagMixin )로 부터 쿼리셋을 가져와서 .filter(depth=2) 조건으로 검색 후 결과를 context에 다시 저장했습니다.

※ TagMixin의 queryset은 context['object_list'] 에 담겨 있습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from myapp.common.common_views import MenuMixin, TagMixin

class TagListView(TagMixin, MenuMixin, generic.ListView):
    model = PyCoding
    template_name = "coding/tags.html"

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)    
        context['object_list'] = super().get_queryset().filter(depth=2)
        context['q'] = self.request.GET.get("q")
        context.update(self.getMenuList)
        return context

63.4 urls.py 추가 및 tags.html 파일 생성

urls.py에 tags/ path를 추가하고, 화면에 표시할 tags.html을 생성하였습니다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#myapp/coding/urls.py
from django.urls import path
from . import views

app_name = "coding"

urlpatterns = [    
    path('coding/<int:pk>/', views.CodingDetail.as_view(), name='coding_detail'),
    path('tags/', views.TagListView.as_view(), name='tag_list'),

]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{% extends "base/base.html" %}
{% load static %}
{% load extr_blog %} 
{% block content %}
<div class="d-sm-flex align-items-center justify-content-between mb-4">
    <h1 id="title_text" class="h3 mb-0 text-gray-800"><span id="{{pageInfo.title}}"> "{{q}}" TAG LIST </span></h1>     
</div>
<!-- Content Row -->
<div class="row">
    <div class="col-lg-8 mb-4">
      <!-- Illustrations -->
        <div class="card shadow mb-4">
            <div class="card-body">
                {%for obj in object_list %}
                <div class="section">
                  <div class="figure"> 
                    <a href="{{obj.get_absolute_url}}">                    
                        <img class="img-fluid px-1 px-sm-1 mt-1 mb-1" style="width: 10rem;" src="{{obj.img_url}}" title="{{obj.title}}"  align="top"/>
                    </a>
                  </div>
                  <div class="px-1 px-sm-1 mt-1 mb-1">                    
                      <a href="{{obj.get_absolute_url}}"><span>{{obj.title}}</span></a>
                      <p>{{obj.get_descript}}</p>                    
                  </div>
                </div>                
                {% endfor %}                                 
            </div>              
        </div>        
    </div>
</div>   
{% endblock %}
{% block livere %}
{% endblock %}  

63.6 브라우저에서 확인

잘나옵니다.^^