From 4b4c5f827da310e607b2257ffe156b316054d0ba Mon Sep 17 00:00:00 2001 From: "Edgar P. Burkhart" Date: Wed, 21 Dec 2022 17:05:23 +0100 Subject: [PATCH] Add search --- .../migrations/0008_auto_20221221_1657.py | 16 ++++++++ nummi/main/static/main/css/nav.css | 24 +++++++++++- nummi/main/templates/main/base.html | 6 +++ nummi/main/urls.py | 1 + nummi/main/views.py | 39 +++++++++++++++++++ 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 nummi/main/migrations/0008_auto_20221221_1657.py diff --git a/nummi/main/migrations/0008_auto_20221221_1657.py b/nummi/main/migrations/0008_auto_20221221_1657.py new file mode 100644 index 0000000..8174089 --- /dev/null +++ b/nummi/main/migrations/0008_auto_20221221_1657.py @@ -0,0 +1,16 @@ +# Generated by Django 4.1.4 on 2022-12-21 15:57 + +from django.contrib.postgres.operations import TrigramExtension, UnaccentExtension +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ("main", "0007_snapshot_file_alter_invoice_file_alter_snapshot_date"), + ] + + operations = [ + TrigramExtension(), + UnaccentExtension(), + ] diff --git a/nummi/main/static/main/css/nav.css b/nummi/main/static/main/css/nav.css index ecf6343..27de1d9 100644 --- a/nummi/main/static/main/css/nav.css +++ b/nummi/main/static/main/css/nav.css @@ -19,7 +19,8 @@ nav { line-height: var(--nav-lh); padding: var(--nav-pad); } -nav > a { +nav > a, +nav > form { display: inline-block; color: inherit; text-decoration: inherit; @@ -40,3 +41,24 @@ nav > a img { vertical-align: top; margin-right: .5rem; } + +nav > form input { + font: inherit; + height: inherit; + border: none; + background: #ffffff35; + padding: 0 var(--gap); +} +nav > form input[type="text"] { + border-radius: var(--radius) 0 0 var(--radius); +} +nav > form input[type="submit"] { + border-radius: 0 var(--radius) var(--radius) 0; +} +nav > form input[type="submit"] { + cursor: pointer; + color: var(--green-text); +} +nav > form input[type="submit"]:hover { + text-decoration: underline; +} diff --git a/nummi/main/templates/main/base.html b/nummi/main/templates/main/base.html index 5b71a72..4672d76 100644 --- a/nummi/main/templates/main/base.html +++ b/nummi/main/templates/main/base.html @@ -39,6 +39,12 @@ accesskey="s"> {% translate "Snapshot" %} + + diff --git a/nummi/main/urls.py b/nummi/main/urls.py index 272fc29..2a76acb 100644 --- a/nummi/main/urls.py +++ b/nummi/main/urls.py @@ -18,4 +18,5 @@ urlpatterns = [ path("snapshot", views.snapshot, name="snapshot"), path("snapshot/", views.snapshot, name="snapshot"), path("snapshot//del", views.del_snapshot, name="del_snapshot"), + path("search", views.search, name="search"), ] diff --git a/nummi/main/views.py b/nummi/main/views.py index 74b5359..ae36576 100644 --- a/nummi/main/views.py +++ b/nummi/main/views.py @@ -1,6 +1,12 @@ from django.contrib.auth import views as auth_views from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin +from django.contrib.postgres.search import ( + SearchQuery, + SearchRank, + SearchVector, + TrigramSimilarity, +) from django.core.paginator import Paginator from django.db import models from django.http import HttpResponse @@ -202,3 +208,36 @@ def del_snapshot(request, uuid): _snapshot = get_object_or_404(Snapshot, id=uuid) _snapshot.delete() return redirect(index) + + +@login_required +def search(request): + _search = request.POST.get("search") + _transactions = ( + Transaction.objects.annotate( + rank=SearchRank( + SearchVector("name", weight="A") + + SearchVector("description", weight="C"), + SearchQuery(_search, search_type="websearch"), + ), + similarity=TrigramSimilarity("name", _search), + ) + .filter(models.Q(rank__gte=0.1) | models.Q(similarity__gte=0.1)) + .order_by("-rank", "-date") + ) + + if _transactions.count() == 0: + _transactions = ( + Transaction.objects.annotate(rank=TrigramSimilarity("name", _search)) + .filter(rank__gte=0.1) + .order_by("-rank", "-date") + ) + + return render( + request, + "main/transactions.html", + { + "transactions": _transactions, + "search": _search, + }, + )