본문 바로가기

Django

[Django] Blog 앱 확장 - 검색 기능

블로그에 검색기능을 추가하겠다.

우선은 전체 페이지에서 검색하는게 아닌 블로그내에서만 작동하게 하도록 만들겠다.

Blog 부분에 테이블 변경 사항이 없으므로 모델 코딩은 불필요하다.

바로 URLconf 코딩부터 시작한다. 뷰에서 검색 폼을 사용하므로 검색 폼을 먼저 코딩하고

다음에 뷰를 코딩하겠다.

 

urls.py 수정

# blog/urls.py

	# Example: /blog.search/
    path('search/', views.SearchFormView.as_view(), name='search')

 

forms.py 수정

검색 기능을 제공하기 위해서 검색 폼을 보여줘야 하고,

검색 폼의 데이터가 제출되어야 뷰가 처리하는 순서이다.

뷰를 코딩하기 전에 폼을 먼저 만들어줘야 한다.

# blog/forms.py

from django import forms


class PostSearchForm(forms.Form):
    search_word = forms.CharField(label='Search Word')

장고는 폼을 클래스로 표현할 수 있다. 그 기능을하는 모듈을 import해준다.

폼을 정의하는 방법은 테이블의 모델클래스를 정의 하는 방법과 매우 유사하다.

 

views.py 수정

기존의 파일에 클래스형 뷰 SearchFormView를 추가해준다.

# blog/views.py

from django.views.generic import ListView, DetailView, TemplateView
from django.views.generic import ArchiveIndexView, YearArchiveView, MonthArchiveView
from django.views.generic import DayArchiveView, TodayArchiveView
from django.views.generic import FormView
from django.conf import settings
from django.db.models import Q
from django.shortcuts import render

from blog.models import Post
from blog.forms import PostSearchForm

#--- FormView
class SearchFormView(FormView): 
    form_class = PostSearchForm 
    template_name = 'blog/post_search.html' 

    def form_valid(self, form): 
        searchWord = form.cleaned_data['search_word']
        post_list = Post.objects.filter(Q(title__icontains=searchWord) |  Q(description__icontains=searchWord) | Q(content__icontains=searchWord)).distinct()

        context = {} 
        context['form'] = form 
        context['search_term'] = searchWord 
        context['object_list'] = post_list 

        return render(self.request, self.template_name, context)   # No Redirection

 

Templates 수정

화면 상당의 Util > Search 메뉴에 링크를 달아주고 검색 폼과 검색 결과를 보여줄 수 있도록

템플릿 파일을 만들어줘야 한다.

#base.html 기존 코드를 다음과같이 수정한다.
<a class="dropdown-item" href="{% 'blog:search' %}">Search</a>

또한 검색 폼과 검색 결과를 한번에 보여줄 수 있도록 템플릿 파일을 만들어줘야한다.

{% extends "base.html" %}

{% block title %}post_search.html{% endblock %}

{% block content %}

    <h1>Blog Search</h1>
    <br>

    <form action="." method="post"> {% csrf_token %}
        {{ form.as_table }}
        <input type="submit" value="Submit" class="btn btn-primary btn-sm">
    </form>

    <br/><br/>

    {% if object_list %}
        {% for post in object_list %}
        <h2><a href='{{ post.get_absolute_url }}'>{{ post.title }}</a></h2>
        {{ post.modify_dt|date:"N d, Y" }}
        <p>{{ post.description }}</p>
        {% endfor %}

    {% elif search_term %}
    <b><i>Search Word({{ search_term }}) Not Found !</i></b>
    {% endif %}

{% endblock %}

페이지가 정상적으로 작동하는 것을 확인할 수 있다.