장고 - Category 기능 학습

Category 기능 학습 목표

  • 많은 카테고리 기능이 있지만, 여기서는 블로그의 상위 카테고리, 하위 카테고리 기능을 구현해보고자 한다.
  • 또한, 해당 카테고리의 숫자를 어떻게 표시할 수 있는지를 알아볼 것이다.

Category 기능 구현 순서

1. 카테고리 모델 작성 (블로그 프로젝트)

  • 경로 : post > models.py
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    from django.db import models
    from ckeditor_uploader.fields import RichTextUploadingField
    from tagging.fields import TagField
    from django.shortcuts import resolve_url
    class Category(models.Model):
    name = models.CharField(max_length=100)
    slug = models.SlugField(max_length=120, unique=True, allow_unicode=True, db_index=True)
    parent_category = models.ForeignKey("self", on_delete=models.SET_NULL, blank=True, null=True, default=None)

    def __str__(self):
    return self.name

    class Post(models.Model):
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, blank=True, null=True)
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=120, unique=True, allow_unicode=True, db_index=True)
    text = RichTextUploadingField()
    material = models.FileField(upload_to='material/%Y/%m/%d',blank=True)
    tag = TagField(blank=True)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

    def __str__(self):
    return self.title + " at " + self.created.strftime("%Y-%m-%d")

2. context_processors 페이지 작성

  • 경로 : post > context_processors.py
    1
    2
    3
    4
    5
    from .models import Category

    def category(request):
    categories = Category.objects.filter(parent_category=None)
    return {'categories':categories}

3. 카테고리를 보여줄 페이지에 삽입할 카테고리 페이지(html) 작성

  • 경로 : post > templates > post > category_list.html

    1
    2
    3
    4
    5
    <div class="accordion" id="category_list">
    {% for category in categories %}
    {% include 'post/part_category_list.html' %}
    {% endfor %}
    </div>
  • 경로 : post > templates > post > part_category_list.html

    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
      <div {% if parent_id %}class="collapse card category_sub_{{parent_id}}" {% else %}class="card" {% endif %}>
    <div class="card-header" style="padding:0;">
    <h2 class="mb-0">
    {% if parent_id %}
    <!-- parent_category를 설정한 카테고리(하위)일 경우 -->
    <a class="btn btn-link" href="{{category.get_absolute_url}}">
    <small>{{category}}</small>
    <span class="badge badge-primary badge-pill">
    <!-- 해당 카테고리를 갖고 있는 포스트 갯수 표시 -->
    {{category.post_set.count}}
    </span>
    </a>
    {% else %}
    <!-- parent_category를 설정하지 않은 카테고리(상위)일 경우 -->
    <button class="btn btn-link" type="button" data-toggle="collapse"
    data-target=".category_sub_{{category.id}}" aria-expanded="false">
    <small>{{category}}</small>
    <span class="badge badge-primary badge-pill">{{category.category_set.count}}</span>
    </button>
    {% endif %}
    </h2>
    </div>
    </div>
    <!-- parent_category가 있는 카테고리가 존재한다면 다음 코드 실행 -->
    {% if category.category_set %}
    <!-- category.id를 parent_id로 부르겠다. -->
    {% with category.id as parent_id %}
    <!-- parent_category가 있는 모든 카테고리마다 상기 html 코드 반복 -->
    {% for category in category.category_set.all %}
    {% include 'post/part_category_list.html' %}
    {% endfor %}
    {% endwith %}
    {% endif %}

4. 카테고리 항목을 필요로 하는 html 페이지에서 해당 카테고리 페이지 호출

  • 경로 : post > templates > post > ***.html
    1
    2
    3
    4
    <div>
    <!-- category 항목 -->
    {% include 'post/category_list.html' %}
    </div>