Django 실전편 ch6

김용녀·2022년 7월 25일
0

3장에서 개발한 blog예제에서는 리스트를 읽는 기능만 있었는데, 각 글마다 tag를 달수있는 기능을 더해보려한다.
모델링에선 tags를 추가하고, URL설계에서 태그 클라우드(태그name만 모인것들)을 보여주는것 하나와 특정 태그를 클릭시 해당 태그 리스트를 보여주는것 하나 총 2개를 개발할것이다.

**models.py**
tags = TaggableManager(blank=True) 

model에는 tags 하나를 입력했지만 taggit 패키지에는 자체 테이블이 저장되어있어, migrate실행시 (우리가 저장한)tags에 taggedItem 컬럼까지 총 2개가 저장된다.

**blog/urls.py**

   Example: /blog/tag/
    path('tag/',views.TagCloudTV.as_view(),name='tag_cloud'),

    # Example: /blog/tag/tagname/
    path('tag/<str:tag>/',views.TaggedObjectLV.as_view(),name='tagged_object_list'),

첫번째 path는 tag집합을 보여주는 tagCloud이고, 두번째 path는 , 태그 클릭시 해당 태그만 모여있는 리스트를 보여준다.

**blog/views**

class TagCloudTV(TemplateView):
    template_name = 'taggit/taggit_cloud.html'

class TaggedObjectLV(ListView):
    template_name = 'taggit/taggit_cloud.html'
    model = Post

    def get_queryset(self):
        return Post.objects.filter(tags__name=self.kwargs.get('tag'))

    def get_context_object_name(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['tagname'] = self.kwargs['tag']
        return context

tagCloud와 taglist를 만드는 뷰 두개가있다 .
TaggedObjectLV는 context변수를 템플릿에 넘기기 위해 get_context_data변수를 추가했다.(super를 이용해 상위클래스의 컨텍스트변수 구함)

Template 추가

다른 template은 다 그대로지만, post_detail.html은 게시글 아래 태그를 추가해야해서 태그 추가 작업을 한다.

post_detail.html - 추가사항
  <b>TAGS</b> <i class="fas fa-tag"></i>
        {% load taggit_templatetags2_tags %}
        {% get_tags_for_object object as "tags" %}
        {% for tag in tags %}
        <a href="{% url 'blog:tagged_object_list' tag.name %}">{{tag.name}}</a>
        {% endfor %}
	&emsp;
        <a href="{% url 'blog:tag_cloud' %}"> <span class="btn btn-info btn-sm">TagCloud</span> </a>
taggit_cloud.html

{% extends "base.html" %}

{% block title %}taggit_cloud.html{% endblock %}

{% block extra-style %}
<style type="text/css">
.tag-cloud {
    width: 40%;
    margin-left: 30px;
    text-align: center;
    padding: 5px;
    border: 1px solid orange;
    background-color: #ffc;
}
.tag-1 {font-size: 12px;}
.tag-2 {font-size: 14px;}
.tag-3 {font-size: 16px;}
.tag-4 {font-size: 18px;}
.tag-5 {font-size: 20px;}
.tag-6 {font-size: 24px;}
</style>
{% endblock %}

{% block content %}
    <h1>Blog Tag Cloud</h1>
    <br>

    <div class="tag-cloud">
        {% load taggit_templatetags2_tags %}
        {% get_tagcloud as tags %}
        {% for tag in tags %}
        <span class="tag-{{tag.weight|floatformat:0}}">
            <a href="{% url 'blog:tagged_object_list' tag.name %}"> {{tag.name}}({{tag.num_times}})</a>
        </span>
        {% endfor %}
    </div>
{% endblock %}

태그들만 모여있는 템플릿이다. 이것역시 base.html을 통해 상속받음

taggit_post_list.html

{% extends "base.html" %}

{% block title %}taggit_post_list.html{% endblock %}

{% block content %}

    <h1>Posts for tag - {{ tagname }}</h1>
    <br>

    {% for post in object_list %}
        <h2><a href='{{ post.get_absolute_url }}'>{{ post.title }}</a></h2>
        {{ post.modify_dt|date:"N d, Y" }}
        <p>{{ post.description }}</p>
    {% endfor %}

{% endblock %}

tag 클릭시 해당 태그가 있는 글 보여준다
리스트뷰에서 받은 컨텍스트변수로 받은 object_list를 순회하며 출력해준다.

profile
어서오세요

0개의 댓글