[django toolBox]파이썬 장고 Taggit을 이용한 태그 검색 기능 구현하기 1
해시태그(hashtag)는 메타데이터 태그로, 해시 기호(#) 뒤에 특정 단어를 쓰면 그 단어에 대한 글을 모아 분류해서 볼 수 있게 합니다.
관련된 내용물을 묶어주는 역할을 해 사용자들이 관심 있는 주제의 내용물을 쉽게 찾을 수 있도록 도와주는데요,
여기서는 이 태그 기능을 django-taggit 을 이용해 손쉽게 구현해 봅니다.
작업 목표: 이 사이트에는 강좌, 레슨, 블로그 등이 있다. 이것을 같은 주제로 태그로 연결하게 할 것이다. 하나의 앱의 태그만 아니라 즉 여러앱을 태그로 연결하는 것이다.
설치
pip install django-taggit
settings.py
INSTALLED_APPS
에 taggit 추가.
# Application definition
INSTALLED_APPS = [
'taggit', #taggit 추가
]
모델에 필드 추가 예시. 블로그의 경우
from taggit.managers import TaggableManager
class blogPost(models.Model):
author = models.ForeignKey(User,on_delete=models.CASCADE)
title = models.CharField(max_length=30)
text = HTMLField()
tags = TaggableManager() #태그 추가
created_date = models.DateTimeField(default=timezone.now)
def get_absolute_url(self):
return reverse("blogs:post_detail", kwargs={"pk": self.pk})
def __str__(self):
return self.title
마이그레잇
python manage.py migrate
우리는 여러 앱에서 태그를 사용하게 할것이므로 context_processors.py 이용 태그를 글로벌 하게 사용가능하게 해야 한다.
context-processors 는 HttpRequest를 인수로 사용하고 사전형(dict) 반환해준다.
코드의 예시를 보자. 위에서 말한 내용처럼 HttpRequest를 인수로 받으며 우리가 작업할 tag를 dict형을 반환하는 간단한 함수를 제작한다.
from taggit.models import Tag
def tags(request):
return {'tags': Tag.objects.all()}
생성한 함수를 어디서든 불러올 수 있어야하므로 settings.py의 template(template변수로 사용할 것이므로)의 options 아래의 context_processors에 넣어준다.
'OPTIONS': {
'context_processors': [
'blog.context_processors.tags',#장고 태그 작업 중
],
태그 입력을 위한 forms.py 작업 예시
class PostForm(forms.ModelForm):
text = forms.CharField(
widget=TinyMCEWidget(
attrs={'required': False, 'cols': 30, 'rows': 10}
)
)
class Meta:
model= blogPost
fields = ['title','text','tags']
help_texts = {
'title': '글의 제목을 입력하세요',
'text': '글을 적어 주세요',
'tags': '태그 - 관련 주제를 콤마(,)로 구분해 입력해 주세요'
}
def save_form(self, request, instance, form, change):
user = request.user
instance = form.save(commit=False)
if not change or not instance.author:
instance.author = user
instance.modified_by = user
instance.save()
form.save_m2m()
return instance
추가로 태그 쿼리를 위한 views.py 작업의 예시도 추가하니 참고해 주세요.
class PostListView(ListView):
context_object_name = 'posts'
template_name = 'blog/post_list.html'
#ordering = ['-created_date']
#model = blogPost
def get_queryset(self):
queryset = blogPost.objects.all().order_by('-created_date')
tag = self.request.GET.get('tag')
if tag:
queryset = queryset.filter(tags__name=tag)
return queryset
html에 추가
이제 준비는 다 끝났다 그대로 가져와 사용만 하면 된다.
<div class="tags">
{% for tag in tags %}
<a href="{% url 'blogs:post_list' %}?tag={{tag.name}}"> {{tag.name}}</a>
{% endfor %}
</div>
실전 과제: 이 태그로 이루어진 블로그 외에 강좌와 레슨도 모두 연결해 보세요. 예를 들어 장고라는 태그를 클릭하면
이 블로그 페이지에 블로그와 강좌, 레슨이 모두 연결되어 나오는 로직을 구현해 보세요.
직접 한번 해 보신 후 다음의 2편을 보시길 추천드립니다.
이글만 보기