#28 검색과 정렬

#28 검색과 정렬

이번에는 Pybo의 index 페이지에 검색기능과 정렬기능을 추가해본다.

1. 검색창 추가

검색창은 페이징 영역 아래쪽에 중간부분에 오도록 만들 것이다. question_list.html 의 페이징 영역 아래부분을

위와 같이 수정해준다.

2. searchForm, 스크립트 코드 작성

그리고 검색영역 아래부분에 검색창에서 입력받은 내용을 뷰 함수에 전달하기 위한 폼을 만들어준다.

hidden 속성으로 검색어(kw)와 페이지번호(page) 데이터를 받아오는 폼이다.

지금까지 페이지번호를 직접 url로 요청했던 링크들도 수정해준다.

{{ <페이지번호> }}

이와 같은 형태였던 링크들을

{{ <페이지번호> }}

이와 같이 변경한 것이다.

게시글, 답글, 댓글 삭제 기능을 구현할 때도 href 값을 #으로 하고 data-XXX 의 형태로 값을 저장만 해두었던 것을

기억할 것이다. 이번에도 그 때와 마찬가지로 스크립트 코드를 통해 이를 처리해야한다. 삭제 기능을 구현할 때와

마찬가지로 스크립트 블록 내에 자바스크립트 코드를 작성해준다.

page-link 클래스의 링크가 클릭될 경우 data-page 로 저장된 페이지번호를 page 변수에 세팅해준 뒤 searchForm 을

제출한다. searchForm 은 kw에는 값이 없으니 빈 문자열이, page에는 자바스크립트 코드에서 설정된 페이지번호가

들어간 채로 GET 방식으로 제출되어 뷰 함수에서 처리된다.

id가 btn_search 인 버튼이 클릭될 경우 kw클래스의 값을 가져와서 kw 변수에 세팅, page 변수는 모든 페이지에 대해

검색해야 하기 때문에 1로 세팅한 뒤 searchForm 을 제출한다. page-link 때와 마찬가지로 searchForm 은 이 값들을

입력값으로 받아 GET 방식으로 제출하여 뷰 함수에서 이를 처리한다.

3. 뷰 함수 수정

이제 pybo/views 디렉토리의 base_views.py 를 수정하여 실제로 searchForm 을 처리해야한다.

먼저 django.db.models 의 Q 함수를 import 한다. 이 함수는 게시글 리스트에서 검색조건에 맞는 글만을

필터링하기 위해 사용된다.

request에서 키워드(kw) 값을 가져온다.

위와 같이 코드를 작성하여 question_list 의 항목들을 필터링한다. 각 게시글의 subject(제목), content(내용),

author.username(글쓴이 이름), answer.author.username(답글 글쓴이들의 이름) 에 kw가 포함되어있는 경우만을

필터링한 것이다. icontains 대신 contains 를 사용할 경우 대소문자를 구분하여 검색결과를 반영할 수 있다.

마지막으로 index 페이지를 렌더링 할 때 넘겨줄 context 에 kw 와 page 도 추가한다. 이렇게 하면 검색 후

index 페이지에서도 내가 검색한 검색어가 그대로 검색창의 텍스트필드에 남아있으며 검색을 위해 페이지를 1로

세팅한 것도 반영된다.

검색 결과가 정상적으로 반영되는 것을 볼 수 있다.

4. 정렬 조건 선택창 추가

이제 정렬기능을 구현할 차례다. 먼저 정렬 기준은 최신순(작성된 날짜가 최신일수록 위에), 추천순(추천 수가 많을수록

위에), 인기순(답글 수가 많을수록 위에) 세 가지로 구현할 것이다.

검색창의 텍스트필드 좌측에 위와같이 선택박스를 생성한다. so 값으로 설정된 선택지가 선택박스에 표시된다.

정렬 기능 또한 searchForm 에서 처리하도록 할 것이다. 정렬 조건인 so를 입력값으로 받아오도록 한다.

정렬 처리를 위한 스크립트 코드도 추가해준다. 정렬 조건인 so 값이 변경된 경우 so는 변경된 so값으로,

page는 1로 설정하여 searchForm 을 제출한다.

django.db.models 에서 이번에는 Count 함수를 import 한다.

request 에서 정렬 기준 so 값을 받아와 그에따라 정렬을 수행한다. annotate 함수와 Count 함수를 사용하여 추천자

수와 답글 갯수를 구할 수 있다. 만약 추천자 수나 답글 갯수가 같다면 작성 날짜가 최신일수록 위에 오도록 하여

정렬한다.

페이지가 다시 렌더링된 후에도 선택한 정렬조건이 남아있도록 하기 위해서 so 값도 context 에 추가한다.

이제 정렬 기능이 정상적으로 동작하는 것을 확인할 수 있다.

from http://scala0114.tistory.com/116 by ccl(A) rewrite - 2021-10-12 15:01:10