인기 Blog라면 각 글마다 달 수 있는 태그 기능이 필요할 테다.
각 글마다 몇 개의 태그를 달고, 또 이러한 태그들을 한눈에 볼 수 있는 기능을 추가해보자.
1. 패키지 설치
처음 태그 기능을 생각했을 때는 새로 모델을 만들고... 상속받고... 어쩌고... 를 해야 할 것만 같았다.
하지만 인기 기능인만큼 django에서 미리 만들어둔 패키지가 존재한다. 개발자 만세!
pip install을 통해 django-taggit 과 django-taggit-templatetags2 를 설치.
똑같이 패키지를 설치하더라도, 설정 파일(즉 settings)에 등록하는 경우와 그렇지 않은 경우가 존재한다.
지금 설치하는 두 패키지는 모두 settings에 등록을 해야 하는데, 이때 어떤 이름으로 등록할지 정해져 있다!!
이는 각 패키지의 공식 문서에서 확인할 수 있다.
애플리케이션 이름은 각각 taggit.apps.TaggitAppConfig / taggit_templatetags2
Settigns 맨 밑에
TAGGIT_CASE_INSENSITIVE = True / TAGGIT_LIMIT = 50 도 야무지게 적어주자. 무슨 뜻인지도 체크!
2. Models 수정
models.py
우선 설치한 taggit 패키지에서 TaggableManager을 import 해주자
이는 taggit 앱 내에서 정의된 클래스!
자체적으로 Tags라는 별칭과 null=True 항목이 정의되어 있다.
또한 taggit 패키지 내부에는 자체 테이블이 정의되어 있으며,
데이터베이스에 Tag, TaggedItem이란 테이블이 자동적으로 추가된다!
이는 이후 Admin 페이지에서 확인해볼 예정.
admin.py
Admin 페이지에서 작성 및 확인이 가능하도록 등록해주자.
list_display에 'tag_list'를 추가하고, 하단에 get_queryset과 tag_list 메서드를 정의.
이제 Admin페이지에 들어가 보자.
taggit이라는 앱에 Tags라는 모델이 추가된 걸 확인할 수 있다.
또한 화면에 보이지는 않지만 TaggedItem이라는 모델이 존재하고 있다.
Tags의 Add를 클릭해보면..!
우리는 설정해준 적이 없는데! 자동적으로 Name과 Slug가 설정되어 있음을 볼 수 있다. 얏호!
3. Urls 수정
urls.py
기존 작성했던 코드 아래에 두 줄을 추가해주자!
각각 TagCloud(태그들 모음 페이지) 각 태그가 달린 Post를 보여주는 url 요청이다.
4. Views.py 수정
views.py
클래스형 뷰 두 개를 작성해준다!
우선 TagCloud를 띄워주는 TagCloudTV함수.
존재하는 태그들을 단순히 페이지에 띄워주는 기능 -> TemplateView 사용!
template_name도 까먹지 말고 잘 적어주자.
그런데 의문. model조차 정해주지 않았는데, 이 함수가 어떻게 model의 tag들을 가져오는 걸까??
이는 이후 html상에 적어줄 {% get_tagcloud %} 템플릿 태그를 통해 이뤄진다.
즉 처리 기능이 view가 아닌 html 파일에 들어있기 때문에 가능해지는 것!
다음은 tag를 클릭했을 때 해당 tag가 달려있는 Post들의 list를 보여주는 TAggedObjectLV함수.
template_name도 잘 적어줬는지 확인!
tag가 달린 Post를 띄워주기 때문에 model 역시 명시해주자.
taggit_post_list.html에 context 변수를 넘겨줘야 하기 때문에 get_context_data()를 정의해준다.
역시나 super(). get_context_data()를 적어주자.
이것이 무엇인가 하니...
밑에서 context를 새롭게 정의할 텐데, 변경 전의 원래 context 변수를 호출해준 것이다! (이제야 알았다)
얘는 또 뭣이다냐?
우선 context를 tagname으로 이름 붙여줬다.
tag를 클릭했을 때 해당 tag가 달린 Post를 구해야 하는데, URL에서 넘겨준 tag 파라미터를 기준으로 찾는다.
이렇게 URL 패턴으로 넘어오는 값을 추출할 때 self.kwargs [ ]로 추출함을 기억하자.
5. Templates 수정 및 작성
1) post_detail.html 수정
post_detail.html(각 Post들의 세부 정보)에서 해당 게시글에 달린 tag를 띄워줄 예정.
또한 이 tag들을 클릭하면, 해당 tag들이 달린 게시글의 리스트를 보여줄 것이다.
post_detail.html
작성해둔 코드 아래에 해당 내용을 추가하자.
우선 {% load taggit_templatetags2_tags %}를 통해 taggit_templatetag2_tag 패키지에 정의된 커스텀 태그를 사용!
get_tags_for_object ← 이 녀석이 우리가 사용할 커스텀 태그. 얘를 tags라고 정의했다.
이를 통해 views에서 보내준 Post 모델에 달린 태그들의 리스트를 추출할 수 있다.
요 tags를 for문으로 돌려 각각 하나씩 받아온다.
href로 blogs앱의 tagged_object_list라는 url을 작동하도록! 이때 tag.name 인자를 함께 넘겨준다.
name은 또 어디서 나타난 건지? → 아까 Admin에서 확인한 것처럼 Tag 모델에 자동으로 생성된 칼럼!
그 밑에는 Tag Cloud에 갈 수 있도록 Url을 연결시켜줬다.
2) taggit_cloud.html 작성
태그들의 모음집인 taggit_cloud.html과 특정 태그를 포함한 게시글 리스트를 보여줄 taggit_post_list.html을 만들 예정.
이때 유의할 점! blogs App - templates 내에 taggit이라는 폴더를 만들어, 그 안에 넣어줘야 한다.
taggit_cloud.html
post_detail.html 처럼 taggit_templatetags2_tags 패키지를 로드.
이번에는 get_tagcloud 라는 커스텀 태그를 사용한다.
이 녀석을 통해 모든 태그를 추출할 수 있다! tags로 이름 붙여주자.
이러한 tags를 for문으로 데굴데굴.
마찬가지로 blogs앱의 tagged_object_list라는 url을 tag.name이라는 인자와 함께 작동!
페이지 상에는 태그의 이름과, 해당 태그가 몇 번 쓰였는지를 보여줄 예정이다.
이를 위해 tag.num_times를 사용해 해당 태그가 몇 번 사용되었는지 띄워줄 수 있다.
3) taggit_post_list.html 작성
taggit_post_list.html
detail.html 에서 태그를 클릭하면, 해당 태그가 포함된 게시글 리스트를 보여주는 페이지다.
우선 제일 위에 tagname이 보이는데, 얘는 또 어디서?
아까 view에서 context 변수로 보내준 게 바로 요 녀석이다.
이를 통해 해당 태그를 클릭했을 때, url에서 넘어온 tag 파라미터를 찾아온 것!
object_list는 아까 TaggedObjectLV view에서 넘겨준 context 변수의 이름(default로 정해져 있음을 배웠다).
여기에는 특정 tag가 달려 있는 게시글의 리스트가 담겨 있다.
요 녀석도 for문으로 데굴데굴데굴.
post.get_absolute_url을 통해 해당 게시글의 detail 페이지로 이동할 수 있도록 해주자.
title, modify_dt, description도 같이 띄워주도록!
타닥타닥 잘 쳤다면, 어떻게 작동하는지 확인해보자.
Admin페이지에서 Post를 작성하면, 이렇게 Tags를 작성할 수 있다.
해당 글의 detail 페이지! 적성한 태그들도 잘 뜬다. TagCloud로 이동하는 href도 보인다.
태그 라는 태그를 클릭했을 때 화면.
태그 라는 태그를 붙인 글5와 글6이 잘 뜨는 것을 확인할 수 있다.
마지막으로 detail 페이지에서 TAGCLOUD를 클릭했을 때 이동하는 TagCloud 페이지.
Post 모델에 존재하는 모든 태그들과, 해당 태그가 사용된 횟수를 확인할 수 있다. 얏호!
'source-code > Django' 카테고리의 다른 글
Blogs App _ 검색 기능 (0) | 2021.01.04 |
---|---|
Blogs App _ 댓글 기능 (0) | 2021.01.02 |
Blogs App (0) | 2020.12.31 |
Books App _ log 만들기 (0) | 2020.12.30 |
Books App _ home 만들기 (0) | 2020.12.30 |