mirror of
https://github.com/umap-project/umap.git
synced 2025-04-28 19:42:36 +02:00
feat: basic filtering by tags
This commit is contained in:
parent
39f38a9cdf
commit
1344fe6b46
5 changed files with 46 additions and 4 deletions
|
@ -323,7 +323,10 @@ CREATE EXTENSION btree_gin;
|
||||||
ALTER TEXT SEARCH CONFIGURATION umapdict ALTER MAPPING FOR hword, hword_part, word WITH unaccent, simple;
|
ALTER TEXT SEARCH CONFIGURATION umapdict ALTER MAPPING FOR hword, hword_part, word WITH unaccent, simple;
|
||||||
|
|
||||||
# Now create the index
|
# Now create the index
|
||||||
CREATE INDEX IF NOT EXISTS search_idx ON umap_map USING GIN(to_tsvector('umapdict', COALESCE(name, ''::character varying)::text), share_status);
|
CREATE INDEX IF NOT EXISTS search_idx ON umap_map USING GIN(to_tsvector('umapdict', COALESCE(name, ''::character varying)::text), share_status, tags);
|
||||||
|
|
||||||
|
# You should also create an index for tag filtering:
|
||||||
|
CREATE INDEX IF NOT EXISTS tags_idx ON umap_map USING GIN(share_status, tags);
|
||||||
```
|
```
|
||||||
|
|
||||||
Then set:
|
Then set:
|
||||||
|
|
|
@ -14,6 +14,7 @@ def settings(request):
|
||||||
"UMAP_DEMO_SITE": djsettings.UMAP_DEMO_SITE,
|
"UMAP_DEMO_SITE": djsettings.UMAP_DEMO_SITE,
|
||||||
"UMAP_HOST_INFOS": djsettings.UMAP_HOST_INFOS,
|
"UMAP_HOST_INFOS": djsettings.UMAP_HOST_INFOS,
|
||||||
"UMAP_ALLOW_EDIT_PROFILE": djsettings.UMAP_ALLOW_EDIT_PROFILE,
|
"UMAP_ALLOW_EDIT_PROFILE": djsettings.UMAP_ALLOW_EDIT_PROFILE,
|
||||||
|
"UMAP_TAGS": djsettings.UMAP_TAGS,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,14 +5,22 @@
|
||||||
<div class="wrapper search_wrapper">
|
<div class="wrapper search_wrapper">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form action="{% firstof action search_url %}" method="get">
|
<form action="{% firstof action search_url %}" method="get">
|
||||||
<div class="col two-third mwide">
|
<div class="col half mwide">
|
||||||
<input name="q"
|
<input name="q"
|
||||||
type="search"
|
type="search"
|
||||||
placeholder="{% firstof placeholder default_placeholder %}"
|
placeholder="{% firstof placeholder default_placeholder %}"
|
||||||
aria-label="{% firstof placeholder default_placeholder %}"
|
aria-label="{% firstof placeholder default_placeholder %}"
|
||||||
value="{{ request.GET.q|default:"" }}" />
|
value="{{ request.GET.q|default:"" }}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="col third mwide">
|
<div class="col quarter mwide">
|
||||||
|
<select name="tags">
|
||||||
|
<option value="">{% trans "Any category" %}</option>
|
||||||
|
{% for value, label in UMAP_TAGS %}
|
||||||
|
<option value="{{ value }}" {% if request.GET.tags == value %}selected{% endif %}>{{ label }}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col quarter mwide">
|
||||||
<input type="submit" value="{% trans "Search" %}" class="neutral" />
|
<input type="submit" value="{% trans "Search" %}" class="neutral" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -486,3 +486,27 @@ def test_cannot_search_deleted_map(client, map):
|
||||||
url = reverse("search")
|
url = reverse("search")
|
||||||
response = client.get(url + "?q=Blé")
|
response = client.get(url + "?q=Blé")
|
||||||
assert "Blé dur" not in response.content.decode()
|
assert "Blé dur" not in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_filter_by_tag(client, map):
|
||||||
|
# Very basic search, that do not deal with accent nor case.
|
||||||
|
# See install.md for how to have a smarter dict + index.
|
||||||
|
map.name = "Blé dur"
|
||||||
|
map.tags = ["bike"]
|
||||||
|
map.save()
|
||||||
|
url = reverse("search")
|
||||||
|
response = client.get(url + "?tags=bike")
|
||||||
|
assert "Blé dur" in response.content.decode()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.django_db
|
||||||
|
def test_can_combine_search_and_filter(client, map):
|
||||||
|
# Very basic search, that do not deal with accent nor case.
|
||||||
|
# See install.md for how to have a smarter dict + index.
|
||||||
|
map.name = "Blé dur"
|
||||||
|
map.tags = ["bike"]
|
||||||
|
map.save()
|
||||||
|
url = reverse("search")
|
||||||
|
response = client.get(url + "?q=dur&tags=bike")
|
||||||
|
assert "Blé dur" in response.content.decode()
|
||||||
|
|
|
@ -334,12 +334,18 @@ class TeamMaps(PaginatorMixin, DetailView):
|
||||||
class SearchMixin:
|
class SearchMixin:
|
||||||
def get_search_queryset(self, **kwargs):
|
def get_search_queryset(self, **kwargs):
|
||||||
q = self.request.GET.get("q")
|
q = self.request.GET.get("q")
|
||||||
|
tags = [t for t in self.request.GET.getlist("tags") if t]
|
||||||
|
qs = Map.objects.all()
|
||||||
if q:
|
if q:
|
||||||
vector = SearchVector("name", config=settings.UMAP_SEARCH_CONFIGURATION)
|
vector = SearchVector("name", config=settings.UMAP_SEARCH_CONFIGURATION)
|
||||||
query = SearchQuery(
|
query = SearchQuery(
|
||||||
q, config=settings.UMAP_SEARCH_CONFIGURATION, search_type="websearch"
|
q, config=settings.UMAP_SEARCH_CONFIGURATION, search_type="websearch"
|
||||||
)
|
)
|
||||||
return Map.objects.annotate(search=vector).filter(search=query)
|
qs = qs.annotate(search=vector).filter(search=query)
|
||||||
|
if tags:
|
||||||
|
qs = qs.filter(tags__contains=tags)
|
||||||
|
if q or tags:
|
||||||
|
return qs
|
||||||
|
|
||||||
|
|
||||||
class Search(PaginatorMixin, TemplateView, PublicMapsMixin, SearchMixin):
|
class Search(PaginatorMixin, TemplateView, PublicMapsMixin, SearchMixin):
|
||||||
|
|
Loading…
Reference in a new issue