검색 기능 - Pagination (페이지네이션)
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%'
코드 뜯어내기
pagination 기능
한 페이지에 너무 많은 데이터가 있을 때에, 페이지를 나누는 것이다.
다음 페이지로 넘어가기 버튼 또는, 페이지 번호로 가는 버튼을 통해서 페이지를 넘어간다.
views.py
from django.core.paginator import Paginator
page = int(request.GET.get("p", 1))
pagenator = Paginator(search_list, 5)
boards = pagenator.get_page(page)
- 장고에는 페이지를 나눌 수 있는 Paginator가 있다
- page = int(request.GET.get("p", 1))
- client가 요청한 url에 p, 페이지의 변수를 가지고 온다 (여기서 기본 설정은 1이다)
- 기본 설정이 1이란 것은, 첫번째 페이지를 끌고 온다는 것이다
- pagenator = Paginator(search_list, 5)
- search_list는 검색해서 받은 queryset들의 리스트들의 변수 명이다 (search 기능에서 확인 가능)
- search_list를 한 페이지 당 5개씩 가지고 온다
- boards = pagenator.get_page(page)
- pagenator에 저장한 queryset들 (여기서 5개)를 가지고 온다
- pagenator는 각 페이지 당 5개씩 저장이 되어 있고, url에서 불러온 `p`의 값을 `boards`에 저장한다
📌📌📌즉 `page`는 유저가 요청한 몇 번째 페이지 → `pagenator`는 각 페이지 당 몇개의 queryset을 저장할지 지정 → `boards`는 유저가 요청한 페이지의 queryset들을 가지고 온다
HTML
<div class="row mt-2">
<div class="col-12 my-5">
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
{% if boards.has_previous %}
<li class="page-item">
<a class="page-link" href="?searched={{ search }}&sorted={{ sort }}&p={{ boards.previous_page_number }}">이전</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">이전</a>
</li>
{% endif %}
<li class="page-item">
<a class="page-link" href="#">{{ boards.number }}
/
{{ boards.paginator.num_pages }}</a>
</li>
{% if boards.has_next %}
<li class="page-item">
<a class="page-link" href="?searched={{ search }}&sorted={{ sort }}&p={{ boards.next_page_number }}">다음</a>
</li>
{% else %}
<li class="page-item disabled">
<a class="page-link" href="#">다음</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
href="?searched={{ search }}&sorted={{ sort }}&p={{ boards.previous_page_number }}"
- a 태그에 포함된 링크
- 해당 링크를 클릭하면 지금 페이지의 이전 페이지의 정보를 가지고 온다
- 예) 한국을 검색했고, 인기순으로 정렬후, 2번째 페이지를 찾아가기
- /?search='한국'&sorted=popular&p=2
- 여기서 만약에 정렬이 없으면 sort=으로 그냥 넘어간다
'프로젝트 > 여행석사' 카테고리의 다른 글
여행석사 - 댓글 비동기 기능 (0) | 2023.02.22 |
---|---|
여행 석사 - 검색 결과 정렬 기능 (0) | 2023.02.22 |
여행 석사 - 인기 검색어 기능 (0) | 2023.02.22 |
여행석사 - 검색 기능 (0) | 2023.02.22 |
여행 석사 - 소개 (0) | 2023.02.22 |