[장고] 검색기능 구현하기

소요 시간: 5분

다음은 장고(Django)로 만든 블로그에 검색 기능을 추가하는 방법에 대한 더 자세한 설명입니다. 이 가이드는 검색 폼 생성, 검색 뷰 작성, URL 패턴 추가, 검색 결과 템플릿 작성, 데이터베이스 인덱스 추가의 5단계로 구성되어 있습니다. 이 예제에서는 Article이라는 모델을 사용하여 제목과 내용을 검색하는 기능을 구현합니다.


검색 기능의 필요성

검색 기능을 웹사이트에 추가하는 것은 다양한 상황에서 필요합니다. 우선, 웹사이트에 콘텐츠가 많이 쌓여 있거나 정보 구조가 복잡할 때, 사용자가 원하는 정보를 쉽게 찾을 수 있도록 검색 기능이 필수적입니다. 또한, 사용자가 특정 정보를 자주 찾는다는 분석 결과가 있거나, 콘텐츠가 자주 업데이트되는 경우에도 검색 기능을 통해 최신 정보를 접근하기 용이하게 할 수 있습니다.

전문 정보 제공과 전자상거래 사이트

전문 정보를 제공하는 웹사이트나, 제품이 많은 대규모 전자상거래 사이트에서는 검색 기능이 특히 중요합니다. 이를 통해 사용자가 필요한 정보를 빠르게 찾을 수 있으며, 필터링과 정렬 기능을 제공하면 더 큰 편리성을 제공합니다. 이러한 기능은 사용자의 탐색 경험을 개선하고, 전체적인 만족도를 높이는 데 큰 도움이 됩니다.

사용자 경험 개선과 경쟁력 유지

또한, 경쟁 사이트들이 검색 기능을 제공하고 있는 상황이라면, 동일한 기능을 통해 경쟁력을 유지하고 사용자의 기대에 부응하는 것이 중요합니다. 검색 기능을 추가하면 웹사이트의 접근성과 사용성을 높일 수 있습니다.

결론적으로, 웹사이트에 검색 기능을 추가하는 것은 콘텐츠 접근성을 높이고, 사용자 경험을 개선하며, 최신 정보를 쉽게 제공하는 데 필요한 중요한 요소입니다. 이를 통해 웹사이트의 유용성을 증대시키고 사용자 만족도를 높일 수 있습니다.


검색 기능 만들기

1. 모델 설정

우선 검색할 데이터를 저장할 모델을 정의합니다.

from django.db import models

class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()

    def __str__(self):
        return self.title


2. 검색 폼 만들기

검색 폼은 사용자가 검색어를 입력할 수 있도록 하는 부분입니다. Django의 폼 클래스를 사용하여 간단한 검색 폼을 생성할 수 있습니다.

forms.py 파일을 다음과 같이 작성합니다:

from django import forms

class SearchForm(forms.Form):
    query = forms.CharField(label='Search', max_length=100)

여기서는 CharField를 사용하여 검색어를 입력받는 필드를 만들었습니다. label은 폼의 레이블을 지정하며, max_length는 입력 가능한 최대 글자 수를 지정합니다.


3. 검색 뷰 만들기

검색 요청을 처리하는 뷰는 사용자가 입력한 검색어를 받아 데이터베이스에서 관련 게시글을 검색하고, 그 결과를 반환합니다.

views.py 파일을 다음과 같이 작성합니다:

from django.shortcuts import render
from .models import Article  # Article는 블로그 게시글 모델입니다.
from .forms import SearchForm

def search(request):
    form = SearchForm()
    query = None
    results = []
    if 'query' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            query = form.cleaned_data['query']
            results = Article.objects.filter(title__icontains=query)
    return render(request, 'search.html', {'form': form, 'query': query, 'results': results})

여기서 request.GET을 통해 사용자의 검색어를 가져옵니다. form.is_valid()로 폼의 유효성을 검사한 후, cleaned_data를 사용하여 폼 데이터를 안전하게 추출합니다. Post.objects.filter(title__icontains=query)는 제목에 검색어가 포함된 게시글을 검색합니다.

만약 클래스뷰를 사용하고 싶다면 ListView를 사용하여 검색 기능을 처리합니다.

from django.views.generic import ListView
from .models import Article
from .forms import SearchForm

class ArticleListView(ListView):
    model = Article
    template_name = 'article_list.html'
    context_object_name = 'articles'

    def get_queryset(self):
        queryset = super().get_queryset()
        form = SearchForm(self.request.GET)
        if form.is_valid():
            query = form.cleaned_data['query']
            if query:
                queryset = queryset.filter(title__icontains=query) | queryset.filter(content__icontains=query)
        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = SearchForm(self.request.GET)
        return context


4. URL 패턴 추가하기

검색 뷰를 호출할 수 있도록 URL 패턴을 추가해야 합니다.

urls.py 파일을 다음과 같이 작성합니다:

from django.urls import path
from . import views

urlpatterns = [
    path('search/', views.search, name='search'),
    # 다른 URL 패턴들...
]

path('search/', views.search, name='search')는 /search/ URL이 요청되었을 때 search 뷰를 호출하도록 설정합니다.


5. 검색 템플릿 만들기

검색 결과를 사용자에게 보여줄 템플릿을 작성합니다.

search.html 파일을 다음과 같이 작성합니다:

{% extends "base_generic.html" %}

{% block content %}
    <h1>Search</h1>
    <form method="get" action=".">
    {{ form.as_p }}
    <button type="submit">Search</button>
    </form>

    {% if query %}
    <h2>Results for "{{ query }}":</h2>
    <ul>
        {% for article in results %}
        <li>
            <a href="{{ article.get_absolute_url }}">{{ post.title }}</a>
        </li>
        {% empty %}
        <li>No results found.</li>
        {% endfor %}
    </ul>
    {% endif %}
{% endblock %}

템플릿에서는 검색 폼을 표시하고, 검색어가 있을 경우 검색 결과를 보여줍니다. {{ form.as_p }}는 폼을 HTML <p> 태그로 감싸서 표시합니다. 검색 결과가 있을 경우, 각 게시글의 제목을 링크로 표시하고, 결과가 없을 경우 "No results found." 메시지를 표시합니다.


6. 데이터베이스 마이그레이션 및 데이터 추가

모델을 만들었으므로 데이터베이스에 반영합니다.

python manage.py makemigrations
python manage.py migrate

또한, 관리 페이지 또는 쉘을 통해 Article 모델에 테스트 데이터를 추가합니다.


7. 서버 실행 및 테스트

장고 개발 서버를 실행하고 검색 기능을 테스트합니다.

python manage.py runserver

웹 브라우저에서 http://127.0.0.1:8000/search/에 접속하여 검색 기능이 올바르게 동작하는지 확인합니다.


8. 검색 인덱스 추가 (선택사항)

검색 성능을 향상시키기 위해 데이터베이스 인덱스를 추가할 수 있습니다. 예를 들어, title 필드에 인덱스를 추가하여 검색 속도를 높일 수 있습니다.

models.py 파일을 다음과 같이 수정합니다:

from django.db import models

class Post(models.Model):
    title = models.CharField(max_length=200, db_index=True)
    content = models.TextField()
    # 다른 필드들...

db_index=True 옵션을 추가하여 title 필드에 인덱스를 생성합니다. 이를 통해 검색 속도가 개선될 수 있습니다.


요약

이제 장고 블로그에 검색 기능이 추가되었습니다. 사용자가 검색어를 입력하면 해당 검색어가 포함된 게시글 제목을 검색하고 결과를 표시합니다. 필요에 따라 검색 로직을 확장하여 내용, 태그 등 다양한 필드에서 검색할 수 있도록 수정할 수 있습니다.

더 복잡한 검색 기능을 원한다면, Django의 ORM이나 외부 라이브러리(예: Haystack, Elasticsearch)를 활용하여 더 강력한 검색 기능을 구현할 수 있습니다.

장고 리스트