728x90
반응형
미리 페이지네이션을 구현하였고, 이제는 검색 기능을 구현하고자 한다. keyword와 page를 받고, 이를 get방식으로 호출하여 검색 기능을 구현한다.
1. 템플릿 수정하기
1) input과 button 추가하기
<div class="row my-3">
<div class="col-6">
<div class="input-group">
<input type="text" id="search_kw" class="form-control" value="{{ kw|default_if_none:'' }}">
<div class="input-group-append">
<button class="btn btn-outline-secondary" type="button" id="btn_search">찾기</button>
</div>
</div>
</div>
</div>
input과 button을 추가한다. 그리고 input 태그에 id로 search_kw, value로 keyword를 지정한다.
반응형
2) form 추가하기
<form id="searchForm" method="get" action="{% url 'index' %}">
<input type="hidden" id="kw" name="kw" value="{{ kw|default_if_none:'' }}">
<input type="hidden" id="page" name="page" value="{{ page }}">
</form>
- GET 방식으로 요청해야 하므로 method 속성에 "get"로 설정한다.
- kw와 page는 이전에 요청했던 값을 기억하고 있어야 하므로 value에 값을 대입한다.
- 이전에 요청했던 kw와 page의 값은 index 함수로부터 전달한다. view에 index함수를 추가했으므로, action 속성은 {% url 'index' %}로 지정한다.
2. script 추가하기
<a class="page-link" data-page="{{ question_list.previous_page_number }}" href="javascript:void(0)">이전</a>
위 태그는 페이지 이동태그이다.
{% block script %}
<script type='text/javascript'>
const page_elements = document.getElementsByClassName("page-link");
Array.from(page_elements).forEach(function(element) {
element.addEventListener('click', function() {
document.getElementById('page').value = this.dataset.page;
document.getElementById('searchForm').submit();
});
});
const btn_search = document.getElementById("btn_search");
btn_search.addEventListener('click', function() {
document.getElementById('kw').value = document.getElementById('search_kw').value;
document.getElementById('page').value = 1; // 검색버튼을 클릭할 경우 1페이지부터 조회한다.
document.getElementById('searchForm').submit();
});
</script>
{% endblock %}
- class 속성 값으로 "page-link"라는 값을 가지고 있는 a 태그를 클릭할 경우
- a 태그의 data-page 속성 값을 읽어 searchForm의 page 필드에 설정하여 searchForm에 보낸다.
- 템플릿에 있는 찾기 버튼을 클릭할 경우
- 검색어 텍스트 창에 입력된 값을 searchForm의 kw 필드에 설정하여 searchForm에 보낸다. 새로운 검색에 해당되므로 page에 항상 1을 설정하도록 한다.
3. view 추가하기
(... 생략 ...)
from django.db.models import Q
(... 생략 ...)
def index(request):
page = request.GET.get('page', '1') # 페이지
kw = request.GET.get('kw', '') # 검색어
question_list = Question.objects.order_by('-create_date')
if kw:
question_list = question_list.filter(
Q(subject__icontains=kw) | # 제목 검색
Q(content__icontains=kw) | # 내용 검색
Q(answer__content__icontains=kw) | # 답변 내용 검색
Q(author__username__icontains=kw) | # 질문 글쓴이 검색
Q(answer__author__username__icontains=kw) # 답변 글쓴이 검색
).distinct()
paginator = Paginator(question_list, 10) # 페이지당 10개씩 보여주기
page_obj = paginator.get_page(page)
context = {'question_list': page_obj, 'page': page, 'kw': kw}
return render(request, 'pybo/question_list.html', context)
(... 생략 ...)
- Q함수 : OR조건으로 데이터를 조회하기 위해 사용하는 함수
- filter 함수에서 모델 속성에 접근하기 위해서는 이처럼 __ (언더바 두개) 를 이용하여 하위 속성에 접근할 수 있다.
- 중복된 질문을 제거하기 위해 distinct를 사용한다.
728x90
반응형