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
반응형
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
반응형