From fb78f3f993ad008e1ad2b702658a6086097a1239 Mon Sep 17 00:00:00 2001 From: Jake Howard Date: Sun, 31 Jul 2022 15:28:48 +0100 Subject: [PATCH] Use HTMX for search page --- templates/base.html | 1 + website/search/models.py | 74 +++++++++++-------- .../search/templates/search/search_page.html | 31 +++----- .../templates/search/search_results.html | 9 +++ 4 files changed, 63 insertions(+), 52 deletions(-) create mode 100644 website/search/templates/search/search_results.html diff --git a/templates/base.html b/templates/base.html index 2bac4a6..02ecbc4 100644 --- a/templates/base.html +++ b/templates/base.html @@ -40,6 +40,7 @@ + {% block darkmode %} diff --git a/website/search/models.py b/website/search/models.py index 56c96f8..c92df32 100644 --- a/website/search/models.py +++ b/website/search/models.py @@ -1,7 +1,10 @@ from django.core.paginator import EmptyPage, Paginator from django.http.request import HttpRequest +from django.http.response import HttpResponse, HttpResponseBadRequest +from django.shortcuts import render from django.utils.functional import cached_property from rest_framework import serializers +from wagtail.contrib.routable_page.models import RoutablePageMixin, route from wagtail.models import Page from wagtail.query import PageQuerySet from wagtail.search.models import Query @@ -12,7 +15,7 @@ from website.common.utils import TocEntry from website.home.models import HomePage -class SearchPage(BaseContentMixin, BasePage): # type: ignore[misc] +class SearchPage(BaseContentMixin, RoutablePageMixin, BasePage): # type: ignore[misc] max_count = 1 subpage_types: list = [] parent_page_types = ["home.HomePage"] @@ -40,40 +43,49 @@ class SearchPage(BaseContentMixin, BasePage): # type: ignore[misc] def get_context(self, request: HttpRequest) -> dict: context = super().get_context(request) + context["search_url"] = self.reverse_subpage("results") + return context + + @route(r"^results/$") + def results(self, request: HttpRequest) -> HttpResponse: + if not request.GET.get("q", None): + return HttpResponse() serializer = self.SearchParamsSerializer(data=request.GET) - if serializer.is_valid(): - search_query = serializer.validated_data["q"] - context["search_query"] = search_query - filters, query = parse_query_string(search_query) - Query.get(search_query).add_hit() - pages = self.get_search_pages().search(query) + if not serializer.is_valid(): + return HttpResponseBadRequest(serializer.errors) - paginator = Paginator(pages, self.PAGE_SIZE) - context["paginator"] = paginator - page_num = serializer.validated_data["page"] - context["page_num"] = page_num - try: - results = paginator.page(page_num) + search_query = serializer.validated_data["q"] + page_num = serializer.validated_data["page"] - # HACK: Search results aren't a queryset, so we can't call `.specific` on it. This forces it to one as efficiently as possible - if not isinstance(results.object_list, PageQuerySet): - results.object_list = Page.objects.filter( - id__in=list( - results.object_list.get_queryset().values_list( - "id", flat=True - ) - ) - ).specific() - except EmptyPage: - results = [] + context = { + **self.get_context(request), + "search_query": search_query, + "page_num": page_num, + } - context["results"] = results - else: - if "q" in request.GET: - context["invalid_search"] = True - else: - context["initial"] = True + filters, query = parse_query_string(search_query) + Query.get(search_query).add_hit() + pages = self.get_search_pages().search(query) - return context + paginator = Paginator(pages, self.PAGE_SIZE) + context["paginator"] = paginator + + try: + results = paginator.page(page_num) + + # HACK: Search results aren't a queryset, so we can't call `.specific` on it. This forces it to one as efficiently as possible + if not isinstance(results.object_list, PageQuerySet): + results.object_list = Page.objects.filter( + id__in=list( + results.object_list.get_queryset().values_list("id", flat=True) + ) + ).specific() + + except EmptyPage: + results = [] + + context["results"] = results + + return render(request, "search/search_results.html", context) diff --git a/website/search/templates/search/search_page.html b/website/search/templates/search/search_page.html index d45c284..67bd270 100644 --- a/website/search/templates/search/search_page.html +++ b/website/search/templates/search/search_page.html @@ -11,28 +11,17 @@ {% endif %}
-
- -
-
- -
- {% if initial %} -

Enter search terms

- {% elif invalid_search %} -

Invalid search

- {% elif results|length == 0 %} - {% if page_num > paginator.num_pages %} -

There aren't {{ page_num }} page - only {{ paginator.num_pages }}.

- {% else %} -

No results

- {% endif %} - {% else %} - {% for page in results %} - {% include "common/listing-item.html" %} - {% endfor %} - {% endif %} +
+
{% endblock %} diff --git a/website/search/templates/search/search_results.html b/website/search/templates/search/search_results.html new file mode 100644 index 0000000..ecc38d8 --- /dev/null +++ b/website/search/templates/search/search_results.html @@ -0,0 +1,9 @@ +{% load wagtailadmin_tags %} + +{% for page in results %} + {% include "common/listing-item.html" %} +{% endfor %} + +{% if results.has_next %} + +{% endif %}