(2024.07.02. 수정됨.)
주요 파일 경로
blog
|- entry
| |- forms.py
| |- urls.py
| |- views.py
|- templates
|- base.html
검색폼 작성하기
검색창에 사용할 폼을 작성합니다.
검색어 너무 짧으면 검색 결과가 너무 많아지므로 min_length를 이용해 최소 3글자 이상을 입력해야 작동하도록 설정합니다.
# entry/forms.py
from django import forms
...
class Form(forms.ModelForm):
...
class Search(forms.Form):
page = forms.IntegerField(
required=False,
widget=forms.HiddenInput,
initial=1,
)
keyword = forms.CharField(
max_length=19,
min_length=3,
label='검색어',
)
뷰 수정하기
검색 작업을 수행할 search 함수를 작성합니다.
또한 글 목록 페이지에서 검색창을 확인할 수 있도록 index 함수의 context에 "search"라는 이름으로 앞서 작성한 검색폼을 추가합니다.
# entry/views.py
...
from .forms import Form, Search # 추가
...
def index(request: HttpRequest, page: int=1):
...
context.update({
'title': '글 목록',
'paginator': paginator,
'page_obj': page_obj,
'object_list': page_obj.object_list,
'search': Search(), # 추가
})
...
...
# 추가
def search(request: HttpRequest):
context = {}
form = Search(request.GET)
context.update({
'title': '검색 결과',
'object_list': [],
'search': form,
})
if form.is_valid():
keyword = form.cleaned_data['keyword']
queryset = Post.objects.filter(title__icontains=keyword)|Post.objects.filter(content__icontains=keyword)
paginator = Paginator(queryset, 8)
page_obj = paginator.get_page(form.cleaned_data['page'])
context.update({
'paginator': paginator,
'page_obj': page_obj,
'object_list': page_obj.object_list,
})
return render(request, 'index.html', context)
...
Post.objects.filter()|Post.objects.filter()
"|"은 장고에서 OR 검색을 하기 위해 사용하는 연산자입니다.
장고 queryset의 filter method는 기본적으로 AND 조건을 부여하는데, OR 조건을 부여하려면 위 코드와 같이 queryset을 묶어주면 됩니다.
__icontains
"__icontains"는 인수로 넣은 문자열을 대소문자 구분없이 탐색하는 명령어입니다.
"title__icontains='ASDF'"을 넣었다면 title field에 대소문자 구분없이 asdf가 포함된 obejct를 가져옵니다.
"__icontains"가 아닌 "__contains" 명령을 사용하면 대소문자를 구분합니다.
url 추가하기
search라는 이름의 url에 접근하면 검색 함수가 작동하도록 url을 추가해줍니다.
# entry/urls.py
from django.urls import path
from . import views
app_name = 'entry'
urlpatterns = [
...
path('search/', views.search, name='search'), # 추가
...
]
템플릿 수정하기
검색창이 페이지의 상단에 위치하도록 하기 위해 base.html을 수정합니다.
# templates/base.html
<head>
{% include 'style.html' %}
</head>
<body>
<header>
<p><a href="/"><span style="font-size: 28px;"><b>하얀설표 블로그</b></span></a></p>
</header>
<hr>
<div style="display: flex;">
{% include 'is_login.html' %}
{% if search %}
<div style="margin-left: auto;">
<form action="{% url 'entry:search' %}" method="get" style="display: flex;">
{{ search }}
<input type="submit" value="검색">
</form>
</div>
{% endif %}
</div>
<hr>
<h1>{% block title %}{% endblock %}</h1>
<hr>
<main>
{% block main %}{% endblock %}
</main>
<hr>
</body>
<footer>
<p>this site Powered by <a href="https://www.djangoproject.com/">Django</a></p>
<p>Designed by 하얀설표 from <a href="https://django.seolpyo.com/">설표의 장고</a></p>
</footer>
검색해보기
이제 검색 기능을 사용할 수 있게 되었습니다.
검색폼에서 설정한 것처럼 3글자 미만의 검색어를 입력하면 경고 문구가 노출되는 것을 확인할 수 있습니다.

이 글의 댓글 기능은 일부러 막아놓았습니다. 궁금한 내용이 있다면 게시판을 이용해주세요!