本を検索する
CoddyのDjangoジャーニー「モデルと管理サイト」セクションの一部。レッスン 15/23。
本棚には検索ボックスが必要です。検索ページは、訪問者が入力した内容をアドレスから読み取ります。/search/?q=duneでは、?の後の部分がクエリー文字列で、Djangoはその組を辞書のように扱えるrequest.GETに格納します。ヘッダーの検索ボックスは、このアドレスを自動で作成するフォームです。フォームについては「フォーム」セクションで説明します。あるジャンルのページでは、次のように読み取れます。
def by_genre(request):
genre = request.GET.get("genre", "fiction")
books = Book.objects.filter(genre=genre)
return render(request, "books/genre.html", {"genre": genre, "books": books}).get("genre", "fiction")は、アドレスにgenreがない場合にデフォルト値を返します。一方、そこでrequest.GET["genre"]を使うと、500エラーが発生します。値は常にテキストです。?page=2の場合、"2"が返されます。すべてのタイトルには空文字列""が含まれるため、__icontains=""はすべての行に一致します。
チャレンジ
簡単検索ページを追加しましょう。テンプレート books/search.html は用意されており、q と books を受け取ることを想定しています。
books/views.pyに、アドレスからqを読み取り(ない場合は空文字列)、大文字と小文字を区別せずにタイトルにそれを含む本を検索するビューsearchを書きましょう。books/urls.pyに、名前がsearchのルートsearch/を追加しましょう。
「実行」を押して、ヘッダーで dune を検索します。「dune」の検索結果には Dune が表示され、xyz では「該当する本はありません。」と表示されます。
自分で試してみよう
from django.shortcuts import get_object_or_404, render
from .models import Book
def home(request):
books = Book.objects.all()
return render(request, "books/home.html", {"books": books})
def book_detail(request, pk):
book = get_object_or_404(Book, pk=pk)
return render(request, "books/book_detail.html", {"book": book})
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
モデルと管理サイトのすべてのレッスン
自分で練習してみよう: Djangoプレイグラウンド