diff options
author | Christian Pointner <equinox@helsinki.at> | 2024-12-18 14:02:37 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-18 14:02:37 (GMT) |
commit | f6a26b0423eb01704361b5f5a6b7345762868ef5 (patch) | |
tree | 2bfae2b73cbef063cc2a4d82a3d6ebd7d243cd72 | |
parent | c5629ea3f166faa5743ce342be1f401776ad796f (diff) | |
parent | a0af34e28b6013b21ed2d6dfdd9b2db303cad506 (diff) |
Merge pull request #33 from radio-helsinki-graz/simple-search-viewstable
Simple search view for hosts, notes and shows
-rw-r--r-- | program/urls.py | 2 | ||||
-rw-r--r-- | program/views.py | 80 |
2 files changed, 81 insertions, 1 deletions
diff --git a/program/urls.py b/program/urls.py index 78b9af4..bfed531 100644 --- a/program/urls.py +++ b/program/urls.py @@ -28,6 +28,8 @@ urlpatterns = patterns('', url(r'^v2/shows/(?P<slug>[\w-]+)/?$', views.ShowDetailViewV2.as_view()), url(r'^v2/(?P<pk>\d+)/?$', views.TimeSlotDetailViewV2.as_view()), url(r'^v2/show-filters/?$', views.ShowFilterListViewV2.as_view()), + # search view for WordPress 2025 + url(r'^v3/search/?$', views.search) ) if settings.DEBUG: urlpatterns += \ diff --git a/program/views.py b/program/views.py index c369b85..6ddeacb 100644 --- a/program/views.py +++ b/program/views.py @@ -1,8 +1,10 @@ import json from datetime import date, datetime, time, timedelta +from itertools import chain +from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.db.models import Q -from django.http import HttpResponse +from django.http import HttpResponse, JsonResponse from django.shortcuts import get_object_or_404 from django.views.generic.base import TemplateView from django.views.generic.detail import DetailView @@ -356,3 +358,79 @@ def json_timeslots_specials(request): return HttpResponse(json.dumps(specials, ensure_ascii=False, encoding='utf8').encode('utf8'), content_type="application/json; charset=utf-8") + + +def search(request): + q = request.GET.get("q") + page = request.GET.get("page") + types = request.GET.get("types").split(",") if "types" in request.GET else None + + if q is None: + return HttpResponse("query parameter 'q' is required", status=400) + + if types is None or "host" in types: + hosts = list( + Host.objects.filter(name__icontains=q).values( + "id", + "name", + ) + ) + else: + hosts = [] + + if types is None or "note" in types: + notes = list( + Note.objects.filter(title__icontains=q) + .select_related("show", "timeslot") + .values( + "content", + "image", + "show__image", + "show__name", + "show__slug", + "start", + "timeslot", + "title", + ) + ) + else: + notes = [] + + if types is None or "show" in types: + shows = list( + Show.objects.filter(name__icontains=q).values( + "description", + "image", + "name", + "short_description", + "slug", + ) + ) + else: + shows = [] + + # FIXME: this is a very ugly way to "annotate" the results with their type + for host in hosts: + host["type"] = "host" + for note in notes: + note["type"] = "note" + for show in shows: + show["type"] = "show" + + paginator = Paginator(list(chain(hosts, notes, shows)), per_page=10) + + try: + page = paginator.page(page) + except PageNotAnInteger: + page = paginator.page(1) + except EmptyPage: + page = paginator.page(paginator.num_pages) + + return JsonResponse( + { + "count": paginator.count, + "page": page.number, + "pages": paginator.num_pages, + "results": list(page.object_list), + } + ) |