본문 바로가기
프로젝트/여행석사

여행 석사 - 인기 검색어 기능

by JayAlex07 2023. 2. 22.

검색 기능 - 인기 검색어 기능

 

Search의 모델

class Search(models.Model):
    # 검색할 때, 받는 필드
    title = models.CharField(max_length=10)
    # 인기 검색어를 위해 필요한 필드
    count = models.PositiveIntegerField(default=0)

 

views.py의 검색 기능

def search(request):
    popular_list = {}
    if request.method == "GET":
        search = request.GET.get("searched", "")
        sort = request.GET.get("sorted", "")

        if not search.isdigit() and not search == "":
            if Review.objects.filter(
                Q(title__icontains=search)
                | Q(content__icontains=search)
                | Q(place__icontains=search)
            ):
                popular_list[search] = popular_list.get(search, 0) + 1

        for k, v in sorted(popular_list.items(), key=lambda x: -x[1]):
            if Search.objects.filter(title=k):
                s = Search.objects.get(title=k)
                s.count += 1
                s.save()
            else:
                s = Search(title=k, count=v)
                s.save()
        popular = Search.objects.order_by("-count")[:10]

        search_list = Review.objects.filter(
            Q(title__icontains=search)
            | Q(content__icontains=search)
            | Q(place__icontains=search)
            | Q(theme__icontains=search)
            | Q(user_id__profile_name__icontains=search)
        )

        if search:
            if search_list:
                pass

            if sort == "pop":
                search_list = search_list.order_by("-like_users")
                sort="pop"
                print(search_list)

            if sort == "recent":
                search_list = search_list.order_by("-updated_at")
                sort="recent"
                print(search_list)

            page = int(request.GET.get("p", 1))
            pagenator = Paginator(search_list, 5)
            boards = pagenator.get_page(page)

            return render(
                request,
                "articles/search.html",
                {
                    "search": search,
                    # 페이별로 저장된 queryset을 가지고 온다
                    "boards": boards,
                    # 검색어에 대한, 검색된 queryset들의 리스트를 가지고 온다
                    "search_list": search_list,
                    # 검색이 많이 된 순으로 queryset을 정리해서 가지고 온다
                    "popular": popular,
                    # 특정 필드로 인해 정렬된 queryset들을 가지고 온다
                    "sort" : sort,
                },
            )
        else:
            k = "검색 결과가 없습니다 다시 검색해주세요"
            context = {"v": k}
            return render(request, "articles/searchfail.html", context)

 

✍️ from django.db.models import Q

- 주로 .filter ORM을 사용할 때, 어떠한 정보를 찾을 때 사용한다
- 주로 | & ^ 를 사용한다 (순서대로, and, or, xor)

- 예시)
        ORM : Q(question__startswith='Who') | Q(question__startswith='What')
        SQL : WHERE question LIKE 'Who%' OR question LIKE 'What%'

 


 

코드 뜯어내기

 

인기검색어 기능

search에 저장된 값을 가지고 인기 검색어를 구현한다

popular_list = {}
if request.method == "GET":
    search = request.GET.get("searched", "")

	if not search.isdigit() and not search == "":
            if Review.objects.filter(
                Q(title__icontains=search)
                | Q(content__icontains=search)
                | Q(place__icontains=search)
            ):
                popular_list[search] = popular_list.get(search, 0) + 1

	for k, v in sorted(popular_list.items(), key=lambda x: -x[1]):
            if Search.objects.filter(title=k):
                s = Search.objects.get(title=k)
                s.count += 1
                s.save()
            else:
                s = Search(title=k, count=v)
                s.save()
    popular = Search.objects.order_by("-count")[:10]

 

  • if not search.isdigit() and not search == "":
    • 선택적 사항. 빈칸을 검색어라고 착각하거나, 그냥 번호를 검색어로 착각할 수 있어 설정했다
  • popular_list[search] = popular_list.get(search, 0) + 1
    • popular_list에 검색어 search를 key로 찾고, 한번 찾았으니 1을 더해준다
    • .get(key, [value])
      • get을 통해, 딕셔너리에 key가 없으면, key를 넣어주고 value값을 넣어준다
    • 📌📌📌 여기서는 popular_listsearch (검색한 검색어)가 있으면 value에 1을 더해주고,없으면 해당 값을 search 값을 딕셔너리에 넣어주고 0으로 value를 정한 뒤, 1을 더해준다
  • sorted(popular_list.items(), key=lambda x: -x[1])
    • popular_list 딕셔너리에 저장된 데이터를 sorted통해 정렬한다
    • .items()는 딕셔너리에 있는 key와 value를 가져온다
      • 예시) dict_items([('A', 'Geeks'), ('B', 4), ('C', 'Geeks')])
    • key=lambda x: -x[1] 에서는 key를 input으로 가지고 오고, key의 value (-x[1])를 내림차순으로 정렬하는 것
      • 여기서 -x[1]하는 이유는 items()로 key와 value를 불러왔을 때에 tuple 형태로 정보를 가지고 온다
      • x[0]은 key가 되는 것이고 x[1]은 value가 된다

 

for k, v in sorted(popular_list.items(), key=lambda x: -x[1]):
	if Search.objects.filter(title=k):
            s = Search.objects.get(title=k)
            s.count += 1
            s.save()
        else:
            s = Search(title=k, count=v)
            s.save()
  • if Search.objects.filter(title=k)
    • 먄약 Search 모델의 title 필드에 k (key)가 있으면
  • s = Search.objects.get(title=k)
    • s 에 Search 모델에 해당 title필드의 k 값과 같은 queryset을 가지고 오고
  • s.count += 1
    • s의 queryset의 count 필드에 1을 더해주고
  • s.save()
    • 저장을 한다
  • 만약 Search 모델에, 검색한 검색어가 없다면
    • s = Search(title=k, count=v) : Search 모델에 검색어 (k)와, 검색된 개수 (v)를 저장한다

'프로젝트 > 여행석사' 카테고리의 다른 글

여행석사 - 댓글 비동기 기능  (0) 2023.02.22
여행 석사 - 검색 결과 정렬 기능  (0) 2023.02.22
여행석사 - 검색 기능  (0) 2023.02.22
여행석사 - Pagination 기능  (0) 2023.02.22
여행 석사 - 소개  (0) 2023.02.22