Add search
This commit is contained in:
parent
d8b00d91e8
commit
4b4c5f827d
5 changed files with 85 additions and 1 deletions
16
nummi/main/migrations/0008_auto_20221221_1657.py
Normal file
16
nummi/main/migrations/0008_auto_20221221_1657.py
Normal file
|
@ -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(),
|
||||||
|
]
|
|
@ -19,7 +19,8 @@ nav {
|
||||||
line-height: var(--nav-lh);
|
line-height: var(--nav-lh);
|
||||||
padding: var(--nav-pad);
|
padding: var(--nav-pad);
|
||||||
}
|
}
|
||||||
nav > a {
|
nav > a,
|
||||||
|
nav > form {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: inherit;
|
text-decoration: inherit;
|
||||||
|
@ -40,3 +41,24 @@ nav > a img {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
margin-right: .5rem;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -39,6 +39,12 @@
|
||||||
accesskey="s">
|
accesskey="s">
|
||||||
{% translate "Snapshot" %}
|
{% translate "Snapshot" %}
|
||||||
</a>
|
</a>
|
||||||
|
<form id="search" action="{% url 'search' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input type="text" name="search" placeholder="{% translate "Search" %}" {% if search %}value="{{ search }}"{% endif %} />
|
||||||
|
<input type="submit" value="{% translate "Search" %}" />
|
||||||
|
</form>
|
||||||
|
|
||||||
<a href="{% url 'logout' %}"
|
<a href="{% url 'logout' %}"
|
||||||
class="logout"
|
class="logout"
|
||||||
accesskey="l">
|
accesskey="l">
|
||||||
|
|
|
@ -18,4 +18,5 @@ urlpatterns = [
|
||||||
path("snapshot", views.snapshot, name="snapshot"),
|
path("snapshot", views.snapshot, name="snapshot"),
|
||||||
path("snapshot/<uuid>", views.snapshot, name="snapshot"),
|
path("snapshot/<uuid>", views.snapshot, name="snapshot"),
|
||||||
path("snapshot/<uuid>/del", views.del_snapshot, name="del_snapshot"),
|
path("snapshot/<uuid>/del", views.del_snapshot, name="del_snapshot"),
|
||||||
|
path("search", views.search, name="search"),
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
from django.contrib.auth import views as auth_views
|
from django.contrib.auth import views as auth_views
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
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.core.paginator import Paginator
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
@ -202,3 +208,36 @@ def del_snapshot(request, uuid):
|
||||||
_snapshot = get_object_or_404(Snapshot, id=uuid)
|
_snapshot = get_object_or_404(Snapshot, id=uuid)
|
||||||
_snapshot.delete()
|
_snapshot.delete()
|
||||||
return redirect(index)
|
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,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
Loading…
Reference in a new issue