admin: add SearchListMixin mixin and partial template
This commit is contained in:
parent
b35d27c83e
commit
0150a5c58c
|
@ -1,13 +1,15 @@
|
|||
"""passbook admin util views"""
|
||||
from typing import Any, Dict, Optional
|
||||
from typing import Any, Dict, List, Optional
|
||||
from urllib.parse import urlparse
|
||||
|
||||
from django.contrib import messages
|
||||
from django.contrib.messages.views import SuccessMessageMixin
|
||||
from django.contrib.postgres.search import SearchQuery, SearchVector
|
||||
from django.db.models import QuerySet
|
||||
from django.http import Http404
|
||||
from django.http.request import HttpRequest
|
||||
from django.views.generic import DeleteView, ListView, UpdateView
|
||||
from django.views.generic.list import MultipleObjectMixin
|
||||
|
||||
from passbook.lib.utils.reflection import all_subclasses
|
||||
from passbook.lib.views import CreateAssignPermView
|
||||
|
@ -32,6 +34,26 @@ class InheritanceListView(ListView):
|
|||
return super().get_queryset().select_subclasses()
|
||||
|
||||
|
||||
class SearchListMixin(MultipleObjectMixin):
|
||||
"""Accept search query using `search` querystring parameter. Requires self.search_fields,
|
||||
a list of all fields to search. Can contain special lookups like __icontains"""
|
||||
|
||||
search_fields: List[str]
|
||||
|
||||
def get_queryset(self) -> QuerySet:
|
||||
queryset = super().get_queryset()
|
||||
if "search" in self.request.GET:
|
||||
raw_query = self.request.GET["search"]
|
||||
if raw_query == "":
|
||||
# Empty query, don't search at all
|
||||
return queryset
|
||||
search = SearchQuery(raw_query, search_type="websearch")
|
||||
return queryset.annotate(search=SearchVector(*self.search_fields)).filter(
|
||||
search=search
|
||||
)
|
||||
return queryset
|
||||
|
||||
|
||||
class InheritanceCreateView(CreateAssignPermView):
|
||||
"""CreateView for objects using InheritanceManager"""
|
||||
|
||||
|
|
13
passbook/core/templates/partials/toolbar_search.html
Normal file
13
passbook/core/templates/partials/toolbar_search.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
|
||||
<div class="pf-c-toolbar__group pf-m-filter-group">
|
||||
<div class="pf-c-toolbar__item pf-m-search-filter">
|
||||
<form class="pf-c-input-group" method="GET">
|
||||
{# include page data for pagination #}
|
||||
<input type="hidden" name="page" value="{{ page_obj.number }}">
|
||||
<input class="pf-c-form-control" name="search" type="search" placeholder="Search..." value="{{ request.GET.search }}">
|
||||
<button class="pf-c-button pf-m-control" type="submit">
|
||||
<i class="fas fa-search" aria-hidden="true"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
|
@ -7,6 +7,14 @@ document.querySelectorAll("button.pf-c-dropdown__toggle").forEach((b) => {
|
|||
});
|
||||
});
|
||||
|
||||
document.querySelectorAll("input[type=search]").forEach((si) => {
|
||||
si.addEventListener("search", (e) => {
|
||||
if (si.value === "") {
|
||||
si.parentElement.submit();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Modal
|
||||
document.querySelectorAll("[data-target='modal']").forEach((m) => {
|
||||
m.addEventListener("click", (e) => {
|
||||
|
|
Reference in a new issue