본문으로 바로가기

Django Taggit으로 해시태그 검색 정리

category Coding/Django 2018. 4. 29. 18:32
반응형

범위 : #1-55 Searching Images by Hashtag Part One ~ #1-56 Searching by Hashtag part Two


인터넷을 통해 웹서핑을 하다보면 해시태그를 자주 볼 수 있다.

특히 인스타그램 등 SNS에서 자주 볼 수 있는데 형태는 #서울 #한강 이런 형태이다.

Django에는 Taggit이라는 라이브러리가 있어서 이러한 일련의 작업을 편하게 해준다.

공식문서는 https://django-taggit.readthedocs.io/en/latest/ 로 들어가면 된다.

아래와 같은 형태로 태그를 생성, 삭제, 태그로 조회등의 작업을 할 수 있다.


>>> apple = Food.objects.create(name="apple")
>>> apple.tags.add("red", "green", "delicious")
>>> apple.tags.all()
[<Tag: red>, <Tag: green>, <Tag: delicious>]
>>> apple.tags.remove("green")
>>> apple.tags.all()
[<Tag: red>, <Tag: delicious>]
>>> Food.objects.filter(tags__name__in=["red"])
[<Food: apple>, <Food: cherry>]

정말 간단하다. 그냥 기존 Django Restframework에서 작업하던것과 거의 동일하기 때문에 더 쉬워보이는 것 같기도 하다.

먼저 아래의 명령어로 설치한다.


pipenv install django-taggit


대충 위처럼 나오면 정상적으로 설치를 완료한 것이다.

다음으로 settings.py에 추가해줘야 한다.


위처럼 settings.py에 INSTALLED_APPS 부분에 taggit을 추가해준다.

그다음 마이그레이션을 한번 해줘야한다.


python3 manage.py migrate


그다음 runserver를 해보면 정상적으로 돌아가는걸 확인할 수 있다.

다음으로 models.py에 taggit을 import 해준다.


from taggit.managers import TaggableManager


우리는 이미지 모델에 tags라는 필드를 추가할것이다.

아래와 같이 추가한다.


tags = TaggableManager()


추가한 후 makemigrations, migrate를 해준다.

참고로 해시태그를 검색할 때 대소문자를 구별하지 않을 것이라면 settings.py에 아래의 내용을 추가한다.


TAGGIT_CASE_INSENSITIVE = True


이제 어드민 패널에 들어가보면 아래와 같이 TAGGIT이 추가된 걸 볼 수 있다.


다음으로 입력된 해시태그를 기반으로 뭔가 작업을 해줘야한다.

urls.py는 설정했다고 가정하고 views.py에 해시태그 검색기능을 추가해본다.


class Search(APIView):
def get(self, request, format=None):
hashtags = request.query_params.get('hashtags', None)
print(hashtags)

위처럼 작성한 후 접근을 /?hashtags=gucci,gang 으로 해보면 콘솔에 gucci,gang이렇게 출력된다.

저기서 ,를 기준으로 split해주면 배열 형태로 값을 얻을 수 있다.

참고로 검색할 때 deep relationship이란걸 알아두면 편리하다.

(https://docs.djangoproject.com/en/1.11/topics/db/queries/#field-lookups 참고)

최종적으로 아래와 같이 입력


class Search(APIView):
def get(self, request, format=None):
hashtags = request.query_params.get('hashtags', None)

if hashtags is not None:
hashtags = hashtags.split(',')
images = models.Image.objects.filter(tags__name__in=hashtags).distinct()
serializer = serializers.CountImageSerializer(images, many=True)

return Response(data=serializer.data, status=status.HTTP_200_OK)
else:
return Response(status=status.HTTP_400_BAD_REQUEST)


반응형

'Coding > Django' 카테고리의 다른 글

Django Change Password 정리  (0) 2018.04.30
Django Partial Update 정리  (0) 2018.04.30
Django delete(), add(), remove(), @property 정리  (0) 2018.04.23
Django Getting User Feed 정리  (0) 2018.04.22
Django Restframework 정리  (0) 2018.04.20