Djangoにおいてシンプルな検索機能を実装し、その基本的な流れを説明します。
まずは単純にクラスベースビューであるListViewによってモデルのデータを表示させ、そこに検索機能を追加します。ListView自体に関しては本記事では説明しませんので下記ページをご覧下さい。
本記事では下記のBookモデルを使用します。最終的にtitle(タイトル)とautor(著者)に対して検索するシステムを作成します。またmyappというアプリケーションにおいて作成していきます。
myapp/models.py
1 2 3 4 5 6 7 8 9 |
from django.db import models class Book(models.Model): title = models.CharField(max_length=100) author = models.CharField(max_length=100) def __str__(self): return self.title |
まずはBookモデル一覧ページを作成します。テンプレート名は book_list.html と命名していることに注意して下さい。
myapp/views.py
1 2 3 4 5 6 7 |
from django.shortcuts import render from .models import Book from django.views.generic import ListView class BookList(ListView): model = Book |
myapp/urls.py
1 2 3 4 5 6 |
from django.urls import path from . import views urlpatterns = [ path('', views.BookList.as_view(), name='book'), ] |
myapp/templates/myapp/book_list.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>ListViewサンプル</title> </head> <body> <table border="1"> <tr> <th>title</th> <th>author</th> </tr> {% for book in object_list %} <tr> <td>{{ book.title }}</td> <td>{{ book.author }}</td> </tr> {% endfor %} </table> </body> </html> |
適当なデータを登録して表示
検索機能を追加する
次に検索機能を追加します。
myapp/templates/myapp/book_list.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>ListViewサンプル</title> </head> <body> <form action="" method="get"> <input name="query" value="{{ request.GET.query }}" type="text"> <button type="submit">検索する</button> </form> <table border="1"> <tr> <th>title</th> <th>author</th> </tr> {% for book in object_list %} <tr> <td>{{ book.title }}</td> <td>{{ book.author }}</td> </tr> {% endfor %} </table> </body> </html> |
11〜14行目
本記事ではGETメソッドによって検索ワードをビュー側(views.py)へと送ります。12行目の{{ request.GET.query }}はURLのパラメータの値を取得しています。フォームに検索ワードを入力し検索ボタンを押下した際に、フォームに値が表示されたままの状態を実現しています。例えばURLが「myapp/?query=hoge」の場合、hogeがフォームに表示されます。
myapp/views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
from django.shortcuts import render from .models import Book from django.views.generic import ListView from django.db.models import Q class BookList(ListView): def get_queryset(self): q_word = self.request.GET.get('query') if q_word: object_list = Book.objects.filter( Q(title__icontains=q_word) | Q(author__icontains=q_word)) else: object_list = Book.objects.all() return object_list |
9行目〜
get_queryset()はListViewを利用する場合のメソッドで、モデルに登録されたデータすなわちオブジェクトのリストを返します。検索機能はこれらオブジェクトに対してfilterによって絞り込みをかけることによって実装していきます。
10行目
request.GET.get()によってGETメソッドによってリクエストされた値を取得しています。引数には、テンプレート側のフォームのname属性を指定します。仮にフォームに「由紀夫」と入力して検索ボタンを押下すると、URLは下記のようになり、「由紀夫」というワードが q_word に格納されます。
1 |
http://localhost:8000/myapp/?query=由紀夫 |
12〜17行目
q_wordに格納された値によって、filter()で絞り込みをおこなっています。Qオブジェクトは複雑なクエリを記述する場合に利用し、「 | 」はOR を表します。ここではtitleとauthorに対して「__icontains」を付与することによって、q_wordの値を含む部分一致の検索を実現しています。他にも完全一致である「__exact」等があります(フィールドルックアップを参照)
由紀夫で検索した画面
参照ページ
django ドキュメント