JavaSrcipt로 검색 기능 구현
포스트 목록, 포스트 상세 페이지 우측에서 검색 창이 작동하도록 구현 할 것이다.
보통 특정 URL로 접근시 서버에서 처리해 주는 방식은 python으로 하였으나 검색 창에서 사용자의 클릭이 아닌 직접 입력으로 입력된 값을 서버로 보내 원하는 값을 찾도록 하는 것은 javascript로 해야한다.
base.html을 수정하여 검색 창 내용을 서버로 전달
script 부분에서 searchPost() 함수를 입력한다. id="search-input"으로 input 요소의 값을 가져와 함수에서 쓸 수 있도록 하고 onclick="searchPost"로 클릭시 searchPost() 함수를 실행 시키도록한다.
searchPost() 함수의 document.getElementById('search-input').trim();으로 id가 search-input인 요소의 값을 가져오고 뒤쪽의 .trim() 으로 가져온 값의 앞 뒤 공백을 없앤다. searchValue 지역변수 앞의 let은 변수 선언 방법 중 하나 라고 한다.
if문으로 변수 searchValue의 값이 1 보다 크면 location.href정의한 URL즉 blog/search/입력값/ 으로 이동하고 그렇지 않은 경우 검색어가 짧습니다. 라는 문구를 출력한다.
만약 검색어 글자 수 를 제한하지 않는 경우... 예를들어 딱 1글자만 입력했을시 그 1글자와 관련된 무수한 검색결과가 나올것이고 이는 서버 입장에서는 많은 검색량으로 인해 부담이 될 것이고 사용자 입장에서는 길어진 검색 시간이 부담될 것이다. 그렇기 때문에 검색어 글자 수 제한이 있는 것 이라고 한다.
이와 관련해서 Google은 어떻게 한 글자 검색어를 처리하는지 살펴 보았더니 모든 검색 결과를 죄다 출력하는 것이 아닌 최대 20개~25개 페이지의 검색량으로 제한해 놓은 듯 하다.
안타깝게도 눌러도 반응이 없어서 콘솔창을 열고 오류 내역을 보니 함수 searchPost가 정의되지 않았다고 한다. jquery를 import 했음에도 이런 오류가 뜨는것은 여전히 함수를 인식하지 못하기 때문이고 인식을 못하는 것은 순전히 javascript 언어 자체를 인식 시키지 못 했기 때문이 아닐까 생각해서 language="javascript"를 입력하였더니 잘 작동하였다. 저자의 책과 github에는 이런 내용이 없었는데도 잘 작동 했던것을 보면 아무래도 나의 코드와 저자의 코드와 어딘가에서 다른 모양이다.
language="JavaScript"
지금까지는 마우스 클릭만으로만 동작하게 하였지만 이제는 Enter를 눌러도 동작하도록 코드를 추가해 준다.
테스트 코드 작성
python 이라는 단어를 검색한다고 가정 했을시 test_search 함수에서 만들어진 새 포스트에서 한 개 저 위에 만들어진 post_001의 태그까지 합쳐서 총 2개의 검색 결과가 나와야 한다는 내용의 테스트 코드를 작성한다.
urls.py 파일을 수정하여 PostSearch에 연결
URL을 처리할 수 있도록 views.py의 PostSearch 클래스로 연결시켜 준다. 여기서 <str:q>는 검색어 값을 문자열로 받고 이것을 q로 부르겠다는 뜻이다.
views.py 파일에 PostSearch 클래스 추가
PostList 클래스를 상속받아 개발한 기능을 그대로 이용할 수 있도록 한다.
# 1 : 검색 결과를 페이지 넘김 없이 한 페이지에 전부 보여 줄 수 있도록 PostList의 paginate_by를 None로 지정한다.
# 2 : 상속받은 PostList는 ListView를 상속받아 만들어졌다. ListView에서 제공하는 get_queryset() 메서드는 model로 지정된 요소 전체를 가져오는 역할을 하고 PostList는 model = Post로 되어있으므로 get_queryset()의 결과는 Post.objects.all()와 동일하다 PostSearch에서는 검색된 결과만 가져오도록 self.kwargs['q']로 URL을 통해서 넘어온 값을 받아 q 변수에 저장한다.
# 3 : Q는 django에서 제공하는 기능으로 여러 쿼리를 동시에 사용해야 할 때 쓰인다. 이 코드는 title이나 tags의 name에 q(검색값)가 포함된 레코드를 db에서 가져오라는 뜻이다. 여기서 | 은 or 연산자를 뜻하고 &는 and 연산자를 뜻하는것에 유의한다.
# 4 : distinct()는 중복된 요소가 있을 경우 한 번만 나타나게 한다. title와 tags 둘 다 동일한 검색어를 가지게 되는 경우 2번 출력되는 경우를 막기 위함이다.
# 5 : 이 코드는 Search: python (2) 와 같이 몇 개의 검색 결과가 나왔지를 구현하기 위한 코드다.
post_list.html 파일 수정
PostSearch는 PostList를 상속받아 만들어진 클래스이지만 tempate_name을 설정하지 않았으므로 post_list.html을 템플릿으로 사용하도록 하고 search_info가 값으로 넘어오면 사용할 수 있도록 한다.
'Backend > Django + Bootstrap 개발 일지' 카테고리의 다른 글
32. 자기소개 페이지 (0) | 2022.10.15 |
---|---|
31. 대문 페이지 (0) | 2022.10.13 |
29. 사용자 아바타 구현 (0) | 2022.09.15 |
28. Pagination (여러 페이지에 나누어 보여주는 기능) (2) | 2022.09.13 |
27. 폼으로 댓글 기능 구현(댓글 수정, 삭제 기능 구현) (0) | 2022.09.09 |