diadia

興味があることをやってみる。自分のメモを残しておきます。

検索(サーチ)機能を実装する

検索機能を実装したい

データベースからブログの記事内容だったり、商品を検索して結果を表示したい。

それは検索キーワードに合致する結果を表示すれば良い。 キーワードに合致するものだけ抽出する方法は、objects.filter()を使えば解決できる。 結果を表示するにはListViewを使うかViewを使う。もちろんview関数で定めてあげても良い。
ListViewを使った例はこちら。ポイントはクラスインスタンスメソッドを別途定めてあげることだ。

http://torajirousan.hatenadiary.jp/entry/2018/09/25/025035

 

Viewを使った方法(検索フォームの実装含む。)

流れとしては、テンプレートに検索用のフォームタグを設置する。このフォームタグから入力されたキーワードをfilter()メソッドを使って対象のデータオブジェクトに限定し、テンプレートにレンダリングして表示する。

キーワード入力テンプレートの作成

"products/search.html"...

<form action="{% url 'products:product_search' %}" method="GET">
<input name="q" type="search" placeholder="Search Product by keyword" />
<button type="submit">Search</button>
</form>

半年前はmethodGETの存在を知らなかった。検索用のフォームを作るときはmethod="GET"として、検索キーワードを取得する足がかりを作る。action={***}の役割は以下のものです。フォームになんらかのキーワードが入力される。Searchボタンが押されたときに、views.pyの特定のviewが発動します。
{% url "hoge:foo" %}の中身の部分はviews.pyに記述されているviewのうち、どのviewを発動させるかを指定しています。この場合はhogeアプリケーションおviews.pyのfooが発動します。このview名はurls.pyで名前をつけてあげることが必要になります。

views.pyの作成

"products/views.py"...

from django.shortcut import render
from django.views.generic import View


class ProductSearchListView(View):

    def get(self, request, *args, **kwargs():
        
        q = request.GET["q"]
        print(q)             # ちゃんと入力した文字がqに返されているかコンソールで確認する
      object_list = Product.objects.filter(title__icontains=q)
      context = {}
      context["object_list"] = object_list
      return render(request, "products/product_list.html", context)
    

自分が苦労したひとつにdjangoのrequest.POSTやrequest.GETにまず何らかの情報が格納されているという事実を知らなかった。その事実を知ってからもどんな種類の情報が格納されているか分からなかった。調べる術を持たなかった。どんな情報があるか調べるためにrequest.GET,POSTをいじってみるしかない。
具体的には以下の方法が役に立つ。

class ProductSearchListView(view):
    def get(self, request, *args, **kwargs):
        print(request.GET)
        print("=======================")
        print(dir(request.GET))
        print("=======================")
        print(self.request.GET)

dir()はrequest.GET,POSTに含まれている属性?メソッド?が何であるか表示してくれるので、dir()を足がかりに表示された属性?メソッド?を新たに使ってみてどんな情報があるか探索する方法で自分は取り組んできた。

urls.pyの作成

"products/urls.py"...
from django.urls import path

app_name= "products"
urlpatterns = [
    path('search', ProductSearchListView.as_view(), name="product_search"),
        ]

検索結果を表示するhtmlを作成

"product_list.html"...

{% for object in object_list %}

{{ object.title }}}
{{ object.description }}

{% endfor %}