게시물 검색 기능을 구현한다.
제목이나 내용에 내가 입력하는 검색어가 있다면 출력하는 코드를 짜보려고 한다.
코드를 완성했지만 보완이나 수정해야 할 점이 많이 보이는 것 같다.
view.py에 있는 index함수를 통해 게시물들을 나열을 해준다. 그리고 검색어를 입력했을때 제목이나 내용에 해당 검색어가 있으면 출력하게 할려고 search_post라는 함수를 만들었다.
def search_posts(request):
print('searchpost')
# query = request.GET.get('q') # 검색어를 GET 요청에서 가져오기
existing_query = request.session.get('search_query', None)
new_query = request.POST.get('search-post') or request.GET.get('search-post')
print("first query",existing_query,new_query)
# 새로운 쿼리가 들어오면 세션에 저장
if new_query and new_query != existing_query:
request.session['search_query'] = new_query
query = new_query
else:
query = existing_query
# query = request.POST.get('search-post') or request.GET.get('search-post')
results = []
if query:
# 제목 또는 내용에 검색어가 포함된 게시글 검색
results = Post_information.objects.filter(Q(title__icontains=query) | Q(content__icontains=query))
print('searchbar',results)
paginator = Paginator(results, 10) # 페이지당 20개의 게시물을 표시합니다
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
context = {
'page_obj': page_obj,
'results':1,
'query': query,
}
print(context)
print('checking',existing_query,new_query)
return render(request, 'book/index.html', context)
이렇게까지 복잡하게 짤 생각이 없었는데 이렇게 만들게 되었다. 하나씩 설명을 해보겠다.
검색 기능을 구현하는데 문제는 2가지가 있었다.
1. 검색을 했을때 아예 화면에 뜨지 않는 문제
2.페이지를 넘겼을 때 기존의 쿼리 값이 none값으로 바뀌는 문제
1번 문제를 해결해주기 위해서 result 값을 이용했다. 다음 페이지를 누르면 기존의 들어있는 result 값이 변하면서 내가 원하는대로 조건문을 실행시킬 수 없었다. 그리하여 변하지 않는 상수로 고정을 해주고 result값이 1일때 검색어 리스트를 뽑는 html파일을 만들었고 result값이 존재하지 않을때는 전체 게시물을 보여주는 코드를 구현했다.
{% if results == 1%}
<h2>검색 결과 </h2>
<ul class="post-list">
{% for post in page_obj %}
<li class="post-item">
{% comment %} <a href="{% url 'post_detail' post.id %}">{{ post.title }}</a> - {{ post.created_at }} {% endcomment %}
<a href="{% url 'post_detail' post.pk %}" class="post-title">{{ post.title }}</a>
<div class="post-category">{{ post.category }}</div>
<div class="post-meta">{{ post.created_at|date:"Y-m-d H:i" }} / {{ post.author.nickname }} / 조회수:{{ post.views }}</div>
</li>
{% endfor %}
</ul>
{% else %}
<h2>실시간 인기글</h2>
<ul class="post-list">
{% for post in page_obj %}
<li class="post-item">
{% comment %} <div class="post-title">{{ post.title }}</a> {% endcomment %}
<a href="{% url 'post_detail' post.pk %}" class="post-title">{{ post.title }}</a>
{% comment %} <int:pk>/
{% endcomment %}
<div class="post-category">{{ post.category }}</div>
<div class="post-meta">{{ post.created_at|date:"Y-m-d H:i" }} / {{ post.author.nickname }} / 조회수:{{ post.views }}</div>
</li>
{% empty %}
<li>게시글이 없습니다.</li>
{% endfor %}
</ul>
{% endif %}
위와 같이 해결을 해주니 문제 없이 게시물이 뜨길래 남은 한 문제만 해결하면 된다.
사과라는 검색어를 입력했을 때 search_post함수가 실행이 되면서 검색어를 query넣고 페이지를 나눈다. 하지만 다음 버튼을 눌렀을 경우에 query에 사과라는 검색어가 유지되는 것이 아니라 none값을 받는 다는 문제였다.
그래서 생각했던 것이 existing_query와 new_query이다. 세션을 사용하면 함수가 마쳐도 값을 유지할 수 있다.
세션에 저장된 값을 existing_query에 넣어준다. 새로 입력된 검색어가 있으면 new_query에 저장을 해준다. 이후 조건문으로 새로운 검색어가 맞는지 그리고 새로운 검색어와 기존의 검색어를 비교한다.
이 조건이 참이라면 새로운 검색어가 들어왔다고 판단하여 query에 새로운 값으로 업데이트를 해준다.
거짓일 경우 새로운 검색어가 없거나 기존의 검색어와 동일할 경우 기존에 저장되있던 값을 query에 저장을 해준다.
이런 코드를 이용해서 다음 버튼을 눌렀을때 none값을 받는 문제를 해결했다.