상품이 많아지게 되면 검색 기능은 필수입니다.
우리는 장고를 이용해 여러분이 레고 처럼 원하는 기능을 무엇이든 만들 수 있다는 목적으로 진행을 하기때문에
가장 간단한 방식으로 장고 검색 기능을 습득하도록 하겠습니다.
검색 역시도 검색어 자동 완성, 정렬 등 세부적인 기능을 넣을 수 있지만 이 강의에서는 검색의 핵심 구현에 촛점을 두겠습니다.
이 시간을 통해 여러분은 쇼핑몰 뿐만 아니라, 블로그나 게시판 등 원하는 장고 사이트 등 어디에도 검색 기능을 구현 능력을 가지게 됩니다.
(참고로 먼저 이 강의를 보신 후 블로그도에 검색 기능을 추가하는 형태의 강의도 보시고 싶으신 분은
실전(實戰) Django(장고) 강좌 – 프로 블로그 따라 만들기 강의의
“7.실전 블로그 템플릿 설치와 장고 연결 – 사이드바 1 – 최신글과 카테고리 get_absolute_url” 를 추가로 공부 하시면 됩니다. )
검색을 위해 배우게 되는 장고의 기능
검색 기능은 장고 자체의 Q 함수를 이용해서 구현할 수 있습니다.(from django.db.models import Q)
여러분은 Q함수를 통해 가져온 검색어에서 OR조건으로 데이터를 조회하게 되는 것을 배우게 됩니다. 도메인/search/?kw=왕초보
와 같은 형식으로 kw 입력을 받으면 어떻게 이 request를 처리해서 검색하는지 배우게 됩니다.
검색 작업 루틴 확인
우리는 지금까지 쇼핑몰을 만들면서 익숙해진 다음의 루틴을 사용합니다.
1 검색 앱 만들기 – 별도로 검색을 앱으로 분리하겠습니다.
2 템플릿 작업 – 검색어를 입력 받을 검색 form 작업
3 views.py 파일에서 검색결과 view를 만들어줍니다.
4. 함수에서 사용할 템플릿 작성
5. urls.py에 링크에 해당되는 URL 매핑 작성
검색 기능을 앱으로 분리해서 만들어 보겠습니다.
python manage.py startapp search
새로 만든 앱의 templates폴더를 만들고 settings.py에 app을 등록하고(INSTALLED_APPS = [])
그리고 만들어준 templates 폴더를 TEMPLATES = [] 에 다음과 같이 추가합니다.
'DIRS': [os.path.join(BASE_DIR,'search', 'templates/')],
2. 템플릿 작업 – 검색어를 form 을 이용 GET 메소드로 받습니다.
폼 디자인은 부트스트랩을 이용했습니다.
<!-- 부트스트랩 폼 디자인 참고 https://getbootstrap.com/docs/4.0/components/navbar/#forms -->
<form class="form-inline my-2 my-lg-0" action="{% url 'search:searchResult' %}" method="get">
<input class="form-control mr-sm-2" type="search" placeholder="검색" name="kw">
</form>
참고로 CSRF(Cross Site Request Forgery;사이트 간 요청 위조) 방지를 위해 장고에서 제공하는 {% csrf_token %} 을 form 에 넣어줄 수도 있습니다.
{% csrf_token %}
without csrf token: http://127.0.0.1:8000/search/?kw=%EA%B0%9C
with csrf token: http://127.0.0.1:8000/search/?csrfmiddlewaretoken=7rOdBYjtX5mikQ6m7DUvdus3SNrktPoURWpbC4HjvcEAqinrVMIn7I9RzFbjMRfc&kw=%EA%B0%9C
3 views.py 파일 작업
search 앱에 만든 views.py에서 검색결과 view를 만들어줍니다.
방법은 GET으로 온 form 값을 파라미터들을 받게 되면
request 객체에 있는 get은 request.GET.get(‘파라미터값’) 과 같은 형식으로 파라미터를 전달받고
쿼리 필터를 적용하여 반환 결과를 URL 매핑에 추가한 페이지로 보여줍니다.
from django.shortcuts import render
from store.models import Product
from django.db.models import Q
# filter 함수의 Q함수: OR조건으로 데이터를 조회하기 위해 사용하는 함수
# objects.filter() 는 특정 조건에 해당하면 객체 출력 .get('kw') 은 kw만 반환
# __icontains 연산자 : 대소문자를 구분하지 않고 단어가 포함되어 있는지 검사. 사용법 "필드명"__icontains = 조건값
def searchResult(request):
if 'kw' in request.GET:
query = request.GET.get('kw')
products = Product.objects.all().filter(
Q(name__icontains=query) | #이름 검색
Q(description__icontains=query) #설명 검색
)
return render(request, 'search.html', {'query':query, 'products':products})
4. 함수에서 사용할 템플릿 작성
search.html
을 만듭니다.
{% extends 'store/메인.html'%}
{% load static %}
{% block content %}
<h3>검색결과 출력 - 검색어 : <b>"{{ query }}"</b></h3>
{% for product in products %}
<!-- 부트스트랩 카드 사용 https://getbootstrap.com/docs/4.3/components/card/ -->
<div class="card" style="width: 18rem;">
<a href="../product/{{product.pk}}"><img class="card-img-top" src="{{product.imageURL}}"></a>
<div class="card-body">
<h4 class="card-text">{{product.name}}</h4>
<p class="card-text">${{product.price}}</p>
</div>
</div>
{% empty %}
<h4> 결과 없음</h4>
{% endfor %}
{% endblock content %}
5. urls.py에 링크에 해당되는 URL 매핑 작성
search 앱에 urls.py를 만듭니다.
from django.urls import path
from . import views
app_name = 'search'
urlpatterns = [
path('', views.searchResult, name='searchResult'),
]
프로젝트 urls.py 에 search.urls를 등록합니다.
path('search/', include('search.urls')),
자 이제 완성 되었습니다!
이런식으로 여러분들은 원하시는 기능들을 계속 레고 처럼 추가해 갈 수 있어요!