【django】ページ内検索を実装する方法 (objects.filter)

ほとんどのwebサイトにはページ内検索できるようになっており,現代では必須項目となっています

今回はListViewを活用して実装します

ListViewの簡単な実装方法については下記を参照してください

目次

djangoへのページ内検索の実装

headerにformを作成して実装します

今回はFormViewを使用せずに,HTMLだけで行きます

FormViewでやると可読性があがりますが,実装に手間がかかります

HTMLにフォームの作成

まずはテンプレートにFormタグを書きましょう

設置場所はどこでも大丈夫です

<form class="d-flex" action="{% url 'blog' %}" method="get">
    <input name="q" class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
    <button class="btn btn-outline-primary" type="submit">Search</button>
</form>

actionで飛ばしたいurlを指定します

blog/urls.pyからnameを確認してください

inputのname=で指定した変数はクエリパラメータとなります

ListViewでquerysetに検索をかける

次に検索したいモデルを指定します

検索したいListViewを編集していきます

class BlogListView(ListView):
    model = Blog
    template_name = 'blog/blog.html'
    context_object_name = 'results'
    paginate_by = 3

    # これ以降追加
    def get_queryset(self, **kwargs):
        queryset = super().get_queryset(**kwargs)
        query = self.request.GET

        if q := query.get('q'): #python3.8以降
            queryset = queryset.filter(title__icontains=q)

        return queryset.order_by('-created_at')

querysetはモデルのことになります

formで送信したクエリパラメータはself.request.GETを用いると辞書形式で取得できます

ifのところはセイウチ演算子なのでpython3.8以降でしか動きません

実際に検索してみる

formにdjangoと検索してみました

form

searchボタンを押したら次にURLのところにクエリパラメータが追加されているか確認してください

queryparameter

そして検索結果を見てみましょう

result

複数のカラムに対して検索をかける

上記まではタイトルに対して検索をかけていました

他のカラムにも検索をしてみます

AND検索

カンマ区切りで追加します

def get_queryset(self, **kwargs):
    queryset = super().get_queryset(**kwargs)
    query = self.request.GET

    if q := query.get('q'):
        queryset = queryset.filter(content__icontains=q, title__icontains=q) # 追加

    return queryset.order_by('-created_at')

djangoと検索するとcontentにないので結果はありません

pythonと打つと結果が返ってきます

OR検索

Qモジュールを用いるとOR検索ができます

from django.db.models import Q # 追加

def get_queryset(self, **kwargs):
    queryset = super().get_queryset(**kwargs)
    query = self.request.GET

    if q := query.get('q'):
        queryset = queryset.filter(Q(content__icontains=q)|Q(title__icontains=q))

    return queryset.order_by('-created_at')

djangoと検索しても結果が返ってきます

もちろんpythonで検索しても結果が得られます

参考文献

お疲れ様でした

シェアしてくださると嬉しいです!
  • URLをコピーしました!

コメント

コメントする

目次