검색도 사실 큰 어려움은 없지만 새로 알아야 하는 것들이 있다. 필드안에 텍스트를 포함하는 함수나, OR 연산을 할 수 있도록 해주는 라이브러리 등이 그것이다.


생성된 모델

1
2
3
4
class Post(models.Model):
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    title = models.CharField(max_length=50)
    text = models.TextField()

우리가 검색할 모델의 구조는 위와 같다. 블로그라는 가정하에 포스트는 작성자와 제목, 내용이 있으며 이 글에서 내용 검색은 다루지 않고 작성자와 제목에 대해서만 다룬다.


AND, OR

장고에서 필터들의 AND, OR 연산은 어떻게 진행되는가? 사실 AND 연산은 매우 쉽다. 필터안에 다양한 조건을 나열하면 된다. 가령 아래와 같이 말이다.

1
Post.objects.filter(author=user, title='MY_POST_TITLE').order_by('created_date').reverse()

위와같이 입력하면 장고에선 제목이 MY_POST_TITLEuser의 글을 찾아준다. 그럼 OR 연산은 어떻게 진행할까?

1
2
3
4
# 먼저 아래와 같은 라이브러리를 사용해야 한다.
from django.db.models import Q

Post.objects.filter(Q(author=user) | Q(title='MY_POST_TITLE')).order_by('created_date').reverse()

Q( A ) | Q( B )와 같이 사용하며 A이거나 B인 결과만 추출한다. 이정도 알았으면 검색은 뚝딱 만들 수 있겠다.


검색 메소드

1
2
3
[ urls.py ]

path('search', views.search, name='search'),

먼저 위와같이 /search라는 URL에서 검색을 시도할 것이다.

1
2
3
4
5
[ search.html ]

<form action="search">
    <input autocomplete="off" name="value" type="text" placeholder="검색어를 입력하세요.">
</form>

HTML에선 위와같이 action=search, name=value인 폼을 생성하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[ views.py ]
from django.db.models import Q

...

def search(request):
    # name=value인 값을 가져옴 값이 없으면 ''으로 대체함
    value = request.GET.get('value', '')

    # 템플릿에 랜더링 될 변수를 모아놓을 딕셔너리 자료형
    render_args = {
        'value' : value,
    }

    # value의 값이 존재하는 경우
    if not value == '':
        # 포스트를 최신순으로 가져옴
        posts = Post.objects.order_by('created_date').reverse()
        # 제목에 value가 포함되거나 작성자가 value인 포스트만 걸러냄
        posts = posts.filter(Q(title__icontains=value) | Q(author__username=value))
        render_args['posts'] = posts
    return render(request, 'search.html', render_args)
WRITTEN BY

배진오

소비적인 일보단 생산적인 일을 추구하며, 좋아하는 일을 잘하고 싶어합니다 :D
im@baejino.com