본문 바로가기
개발일지/Django

Django - 장고 검색기능 추가 후에 value url로 전달 안됨 현상 - 해결

by 개발에정착하고싶다 2022. 12. 26.

아.... 니 왜이렇게 에러가 많이 나오지? ㅋㅋㅋㅋㅋㅋ

매일마다 나오네..


#1 증상

 

url주소에 보면 검색 후를 기준으로 kw=와 &사이에 내가 입력한 키워드가 나와야지 정상이였다.

하지만 검색을 아무리 해봐도 해당 kw=에 value전달이 안되는 것이였다.

이것을 두고 몇가지 방법을 사용했다


#2 접근 방법

 

1) 우선 저자분의 깃허브 코드, 책에 나와있는 코드, 나의 코드를 대조해가면서 찬찬히 읽고 또 읽었다.

결론적으로 저 kw=에 value가 전달 해주는 경로와 역할을 해주는 몇군데를 집중적으로 의심했다.

# templates/pybo/question_list.html

<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 }}">    
    <input type="hidden" id="so" name="so" value="{{ so }}">
</form>

그리고 바로 위의 question_list.html에 값을 전달해주는 views.py

from django.db.models import Q, Count
from django.core.paginator import Paginator
from django.shortcuts import render, get_object_or_404

from ..models import Question


def index(request):
    """

    print pybo lists
    """
    page = request.GET.get('page', '1')  # page
    kw = request.GET.get('kw', '')  # 검색어
    so = request.GET.get('so', 'recent')  # 정렬기준

    # 정렬
    if so == 'recommend':
        question_list = Question.objects.annotate(
            num_voter=Count('voter')).order_by('-num_voter', '-create_date')

    elif so == 'popular':
        question_list = Question.objects.annotate(
            num_answer=Count('answer')).order_by('-num_answer', '-create_date')

    else:  # recent
        question_list = Question.objects.order_by('-create_date')

    # 조회
    # question_list = Question.objects.order_by('-create_date')
    if kw:
        question_list = question_list.filter(
            Q(subject__icontains=kw) |  # 제목 검색
            Q(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,
        'so': so
    }
    return render(request, 'pybo/question_list.html', context)

위의 두 부분을 유심히 봤다.

그 이유는

1. 해당 form이 검색에 대한 form이라는 것을 알고있었기 때문이다.

2. form 중에서도 input의 id값이 kw에 들어가는 value가 되는 kw는 views.py에서 비롯된다. 

최종적으로는 context를 거쳐서 render를 통해서 지정된 경로인 pybo/question_list.html 로 보내지게 된다는 것을 알아서 였다.


#3 정리

 

그런데 대조를 해봐도 해봐도 별로 잘못된 것은 없어서 혹시나 하는 마음에 코드검사를 해봤다.

그리고 검색기능이 있는 위치를 찾아보니 form 이외에도

# question_list.html

<div class="col-4 input-group">
    <input type="text" class="form-control kw" 
    value="{{ kw|default_if_none:'' }}">
    <div class="input-group-append">
        <button class="btn btn-outline-secondary" 
        type="button" id="btn_search">Search</button>
    </div>
</div>

이 부분이 있었다.

 

이 또한 대조를 해봤다.

 

하지만 도무지 모르겠어서 저자 게시판과 현업으로 프론트엔드에서 근무한지 7년이 넘은 개발자 형에게 물어봤다.

코드를 보내주고 대답을 기다렸더니 거의 3초만에 답변이 온것 같았다.


#4 결론

 

검색기능의 중추를 이루는 것 중 하나인 자바스크립트 코드에 오타가 있었다 ㅠㅠㅠ

<script type="text/javascript">
$(document).ready(function() {
    $(".page-link").on("click", function() {
        $("#page").val($(this).data("page"));
        $("#searchForm").submit();
    });

    $("#btn_search").on('click', function() {
        $("#kw").val($(".kr").val());
        $("#page").val(1); // 검색버튼을 클릭하면 1페이지부터 조회한다.
        $("#searchForm").submit();
    });

    $(".so").on('change', function() {
        $("#so").val($(this).val());
        $("#page").val(1);
        $("#searchForm").submit();
    });
});
</script>

이게 내 기존의 javascript 코드였다.

그리고 중간에 보면

$("#kw").val($(".kr").val());

라는부분이 있다.

즉, 이번 kw에 value가 전달되지 않는 문제는 .kr이라는 오타때문이였다.

결과적으로

<script type="text/javascript">
$(document).ready(function() {
    $(".page-link").on("click", function() {
        $("#page").val($(this).data("page"));
        $("#searchForm").submit();
    });

    $("#btn_search").on('click', function() {
        $("#kw").val($(".kw").val());
        $("#page").val(1); // 검색버튼을 클릭하면 1페이지부터 조회한다.
        $("#searchForm").submit();
    });

    $(".so").on('change', function() {
        $("#so").val($(this).val());
        $("#page").val(1);
        $("#searchForm").submit();
    });
});
</script>

이렇게 바꾸어주었더니 정상적으로

이렇게 값이 잘 전달된 것을 확인할 수 있었다.

정말 그형이 저 코드의 존재를 확인해주지 않았다면 나는 엄한곳에서 문제를 확인하고 확인하느라 어떻게 해야할지도 몰랐을것같다..

더불어서 검색의 value 전송에 대해서 javascript도 영향이 있다는 것을 알게 되었다.