카테고리 기능 구현하기

Posted on 2021-08-25 by GKSRUDTN99
Django로 웹사이트 만들기 장고

Category 모델 만들기

models.py에 Category 모델 만들기

blog/models.py에 다음 내용을 작성한다.

# blog/models.py
...
class Category(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=200, unique=True, allow_unicode=True)

    def __str__(self):
        return self.name
...

unique=True로 설정하면 동일한 name을 갖는 카테고리를 또 만들 수 없다.

SlugField는 사람이 읽을 수 있는 텍스트로 고유 URL을 만들고 싶을 때 주로 사용한다.

allow_unicode=True를 통해 원래 SlugField가 지원하지 않는 한글도 들어갈 수 있도록 한다.

Post 모델에 category 필드 추가하기

# blog/models.py
...

class Post(models.Model):
    title = models.CharField(max_length=30)
    hook_text = models.CharField(max_length=100, blank=True)
    content = models.TextField()

    head_image = models.ImageField(upload_to='blog/images/%Y/%m/%d', blank=True)
    file_upload = models.FileField(upload_to='blog/files/%Y/%m/%d', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    author = models.ForeignKey(User, null=True, on_delete=models.SET_NULL)

    category = models.ForeignKey(Category, null=True, on_delete=models.SET_NULL)
    def __str__(self):
        return f'[{self.pk}]{self.title} :: {self.author}'

    def get_absolute_url(self):
        return f'/blog/{self.pk}/'

    def get_file_name(self):
        return os.path.basename(self.file_upload.name)

    def get_file_ext(self):
        return self.get_file_name().split('.')[-1]

...

마이그레이션하기

python manage.py makemigrationspython manage.py migrate를 수행한다.

admin.py에 Category 모델 등록하기

# blog/admin.py

from django.contrib import admin
from .models import Post, Category

admin.site.register(Post)

class CategoryAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('name', )}

admin.site.register(Category, CategoryAdmin)

prepopuliated_field를 통해 Category 모델의 name 필드에 값이 입력됐을 때 자동으로 slug가 만들어 지도록 한다.

Meta로 모델의 복수형 알려주기

위 상태로 admin 페이지에 들어가면 Category 모델의 복수형인 Categories가 아니라, Categorys라고 표시되어 있는 것을 확인할 수 있다.

이를 수정하기 위해 verbose_name_plural을 추가해 복수형을 직접 지정한다.

# blog/models.py
...

class Category(models.Model):
    name = models.CharField(max_length=50, unique=True)
    slug = models.SlugField(max_length=200, unique=True, allow_unicode=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = 'Categories'
...

새 카테고리 등록하기

admins.py에서 CategoryAdmin클래스를 따로 작성하여 두었기 때문에, name 필드만 작성해도 slug필드가 알맞게 채워지는 것을 확인할 수 있다.

카테고리를 빈 칸으로 남겨두기

위의 Post모델에서 category필드에 null=True를 적용하여 카테고리를 지정하지 않아도 저장이 될 것 같지만, 저장이 되지 않는다.

정상적으로 저장이 되게 하기 위해선, blank=True도 추가해 주어야 한다.

# blog/models.py
...
category = models.ForeignKey(Category, null=True, blank=True, on_delete=models.SET_NULL)
...