Django 실전편 ch8

김용녀·2022년 7월 26일
0

블로그 태그 , 댓글 기능에 이어서 포스트 검색기능을 개발해보려한다.
따로 만들필요없이 장고 내에 있는 쿼리를 처리하도록 도와주는 Q-객체를 이용할수 있다. 화면 설계는 다음과같이 한다.search 템플릿을 따로 만들고,결과화면이 폼을통해 나오기때문에 검색템플릿과 결과 템플릿을 따로 만들 필요가 없다.

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

urls파일에 추가해준다.

from django import  forms

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

장고에서 폼 기능을 도와주는 forms.py 파일이다. form모듈을 임포트해서 form을 정의하는데, 모델링 과정과 유사하다. 폼 내의 레이블을 정의하는 과정이다.

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

검색폼으로 이용할 PostSearchForm을 임포트하고 (forms.py에 정의한 클래스), 검색기능에 필요한 Q클래스를 임포트한다.

Form을 위한 제네릭 클래스 뷰 를 이용해준다. FormView는 GET요청시 폼화면을 보여주고 입력을 기다린다. POST 요청시 FormVIew가 자체적으로 데이터 유효성 검사후, form_valid함수를 실행한후 적절한 URL로 redirect한다.
Q객체는 filter안에서 다양한 검색 조건을 실행하도록 도와준다.
icontains는 대소문자 구분X검사
render()는 템플릿파일과 컨텍스트를 압축시켜 HttpResponse 객체로 반환시킨다.

Template

<a class="dropdown-item" href="{% url 'blog:search' %}">Search</a>

base.html에 검색 메뉴가 보이도록 추가해준다.

post_search.html 작성

{% 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_date|date:"N d, Y" }}
    <p>{{ post.description }}</p>
{% endfor %}
{% elif search_term %}
    <b><i>Search Word({{ search_term }})Not Found</i></b>
{% endif %}
{% endblock %}


먼저 검색폼을 만든다. post 방식을 통해 submit한다. form을 테이블방식으로 보여주는데, 이때 form은 뷰에서 넘어온 PostSearchForm 객체다

if object_list에 해당 객체가 있는경우, post객체들의 속성(title,description,date)들을 출력한다.

search_term은 결과값이 없는경우, 해당 문자들을 출력하도록 했다.

profile
어서오세요

0개의 댓글