M:N 관계를 배운 이후에 Hash Tag 기능을 사용하게 되었다.
1. Model에 Hashtag 추가하기
#movies/models.py (main app/models.py)
class Hashtag(models.Model):
content = models.CharField(max_length=30, unique=True)
class Movie(models.Model):
...
hashtag = models.ManyToManyField(Hashtag, blank=True)- 해쉬태그라는 class를 새로 만든다. 그리고 Movie에는 ManyToManyField를 사용해서 hastag field를 추가해 주었다.
💡
unique = True 는 어떤 속성일까?
- 동일한 해쉬태그의 경우, 복수의 값은 인정하지 않기 위해서 추가한 속성이다.
2. 게시물 저장할 때 hashtag만 따로 받아서 저장하기
#movies/views.py
def create(request):
if request.method == "POST":
form = MovieForm(request.POST)
if form.is_valid():
movie = form.save(commit=False)
movie.user = request.user
movie.save()
# 해시태그 처리하기
content = request.POST.get('content')
c_list = content.split(' ') # 공백으로 분리한다
for c in c_list:
if "#" in c: # 만약 단어에 #이 붙어있으면 tag로 저장한다.
hashtag, created = Hashtag.objects.get_or_create(
content = c,
)
movie_ = Movie.objects.get(pk=movie.pk)
movie_.hashtag.add(hashtag)
return redirect("movies:detail", movie.pk)
else:
form = MovieForm()
context = {
"form": form,
}
return render(request, "movies/create.html", context)- movie라는 새로운 데이터를 받을 때, 저장하고 나서 해시태그를 따로 분리해서 저장하는 과정을 거친다. 중간에 (해시태그 처리하기) 부분을 참고한다.
- 여기에서 .get_or_create 라는 메서드를 처음 사용해 보았는데, 이것은 tuple을 반환한다.
- 첫번째 인자로는 값을 두번째 인자로는 이미 있는지 혹은 새로만들었는지를 Boolean type으로 반환한다.
3. 각 게시물에서 해시태그는 링크를 포함한 내용으로 다시 만들기
- 여기에서 사용한 것이 Django Custom Template Filter 였다. (처음 들어봄)
- 먼저 지금 작업하고 있는 app 안에
templatetag라는 이름의 폴더를 만든다.
__init__.py를 작성한다.
- 사용자 지정태그 (여기에서는
make_link.py를) 만든다.

- 사진을 보며 확인해보면 movies/templatetags의 구조를 확인할 수 있다.
# make_link.py
from django import template
register = template.Library()
@register.filter
def add_link(value):
content = value.content + ' '
tags = value.hashtag.all()
# 문자열을 링크가 포함한 문자열로 대체한다.
for tag in tags:
content = content.replace(tag.content, f'<a href="/movies/{tag.pk}/hashtag/">{tag.content}</a>')
return content
- 이제 새로운 템플릿을 적용할 게시글 html로 가본다.
# movies/templates/detail.html
{% load make_link %}
{% block content %}
<h2>영화 정보 상세</h2>
<hr>
<h3>{{ movie.pk }} 번째 영화 : {{ movie.title }}</h3>
<br>
<p>{{ movie|add_link|safe }}</p>
...
- 상단에 load를 작성해서 템플릿 태그를 불러와 준다.
- | 를 이용해 필터를 적용하고, safe 필터를 통해 출력 전 추가 HTML ESCAPE 가 필요하지 않은 형태의 문자열로 표시한다.

영화의 상세 페이지로 들어가 보면, 이제 해쉬태그에 링크가 적용된 것을 확인할 수 있다.
4. 해쉬태그를 통한 검색 구현하기
- 해쉬태그를 눌렀을 때 이동할 경로 설정
# movies/urls.py ... path("<hashtag_pk>/hashtag/", views.hashtag, name="hashtag"), ]
- 실행할 함수 설정
# movies/views.py def hashtag(request, hashtag_pk): hashtag = get_object_or_404(Hashtag, pk=hashtag_pk) movies = hashtag.movie_set.order_by('-pk') context = { 'hashtag':hashtag, 'movies':movies, } return render(request, "movies/hashtag.html", context)
- html 파일 설정
# movies/templates/hashtag.html {% extends 'base.html' %} {% block content %} <h2> {{ hashtag.content }} </h2> <p> {{ movies|length }}개의 게시글 </p> <hr> <div> <h3>{{ hashtag.content}} (을)를 태그한 글 </h3> <br> {% for movie in movies %} <h3> {{ movie.title }} </h3> <p> {{ movie.comment_set.all|length }}개의 댓글 </p> <a href="{% url 'movies:detail' movie.pk %}" class="btn-primary btn-sm"> 상세글로 바로가기 </a> {% endfor %} </div> {% endblock content %}최종결과

Uploaded by N2T