parent
355c56243e
commit
bff6631754
@ -5,8 +5,15 @@ import re
|
|||||||
import django_filters
|
import django_filters
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.contrib.gis.measure import D
|
from django.contrib.gis.measure import D
|
||||||
from django.contrib.postgres.search import SearchHeadline, SearchQuery
|
from django.contrib.postgres.search import (
|
||||||
from django.db.models import F, Q
|
SearchVector,
|
||||||
|
SearchQuery,
|
||||||
|
SearchRank,
|
||||||
|
SearchHeadline,
|
||||||
|
TrigramSimilarity,
|
||||||
|
)
|
||||||
|
from django.db.models import Q, F, Func
|
||||||
|
from django.db.models.functions import Greatest, Lower
|
||||||
from django.http import QueryDict
|
from django.http import QueryDict
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
@ -18,6 +25,7 @@ from .models import (
|
|||||||
RecurrentImport,
|
RecurrentImport,
|
||||||
ReferenceLocation,
|
ReferenceLocation,
|
||||||
Tag,
|
Tag,
|
||||||
|
remove_accents,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -531,18 +539,27 @@ class SimpleSearchEventFilter(django_filters.FilterSet):
|
|||||||
return qs
|
return qs
|
||||||
|
|
||||||
def custom_filter(self, queryset, name, value):
|
def custom_filter(self, queryset, name, value):
|
||||||
|
value = remove_accents(value)
|
||||||
search_query = SearchQuery(value, config="french")
|
search_query = SearchQuery(value, config="french")
|
||||||
qs = queryset.filter(
|
|
||||||
Q(title__icontains=value)
|
search_vector = SearchVector(
|
||||||
| Q(category__name__icontains=value)
|
"title", weight="A", config="french"
|
||||||
| Q(tags__icontains=[value])
|
) + SearchVector("description", weight="B", config="french")
|
||||||
| Q(exact_location__name__icontains=value)
|
|
||||||
| Q(description__icontains=value)
|
# Full-text rank
|
||||||
)
|
qs = queryset.annotate(
|
||||||
|
rank=SearchRank(search_vector, search_query),
|
||||||
|
similarity=Greatest(
|
||||||
|
TrigramSimilarity(Func(Lower("title"), function="unaccent"), value),
|
||||||
|
TrigramSimilarity(
|
||||||
|
Func(Lower("description"), function="unaccent"), value
|
||||||
|
),
|
||||||
|
),
|
||||||
|
relevance=F("rank") + F("similarity"),
|
||||||
|
).filter(Q(rank__gte=0.5) | Q(similarity__gte=0.3))
|
||||||
|
|
||||||
for f in [
|
for f in [
|
||||||
"title",
|
"title",
|
||||||
"category__name",
|
|
||||||
"exact_location__name",
|
|
||||||
"description",
|
"description",
|
||||||
]:
|
]:
|
||||||
params = {
|
params = {
|
||||||
@ -556,7 +573,7 @@ class SimpleSearchEventFilter(django_filters.FilterSet):
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
qs = qs.annotate(**params)
|
qs = qs.annotate(**params)
|
||||||
return qs
|
return qs.order_by("-relevance")
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Event
|
model = Event
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
{% if paginator_filter.paginator.num_pages != 1 %}
|
{% if paginator_filter.paginator.num_pages != 1 and paginator_filter|length > 0 %}
|
||||||
<span>
|
<span>
|
||||||
{% if paginator_filter.has_previous %}
|
{% if paginator_filter.has_previous %}
|
||||||
<a href="{{ paginator_filter.paginator.url_first_page }}" role="button">« premier</a>
|
<a href="{{ paginator_filter.paginator.url_first_page }}" role="button">« premier</a>
|
||||||
<a href="{{ paginator_filter.url_previous_page }}" role="button">précédent</a>
|
<a href="{{ paginator_filter.url_previous_page }}" role="button">précédent</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<span>Page {{ paginator_filter.number }} sur {{ paginator_filter.paginator.num_pages }}</span>
|
<span>Page {{ paginator_filter.number }}
|
||||||
|
{% if not nomax %}sur {{ paginator_filter.paginator.num_pages }}{% endif %}
|
||||||
|
</span>
|
||||||
{% if paginator_filter.has_next %}
|
{% if paginator_filter.has_next %}
|
||||||
<a href="{{ paginator_filter.url_next_page }}" role="button">suivant</a>
|
<a href="{{ paginator_filter.url_next_page }}" role="button">suivant</a>
|
||||||
|
{% if paginator_filter.count < 9999999998 %}
|
||||||
<a href="{{ paginator_filter.paginator.url_last_page }}" role="button">dernier »</a>
|
<a href="{{ paginator_filter.paginator.url_last_page }}" role="button">dernier »</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
</span>
|
</span>
|
||||||
{% else %}
|
|
||||||
Page 1 sur 1
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<a href="{% url 'event_search_full' %}">Recherche avancée {% picto_from_name "chevron-right" %}</a>
|
<a href="{% url 'event_search_full' %}">Recherche avancée {% picto_from_name "chevron-right" %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
{% if has_results or categories %}
|
{% if has_results or categories or tags or places or organisations or rimports %}
|
||||||
<div id="results">
|
<div id="results">
|
||||||
{% if categories %}
|
{% if categories %}
|
||||||
<div class="message success">
|
<div class="message success">
|
||||||
@ -87,16 +87,13 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<p>
|
|
||||||
{{ paginator_filter.paginator.count }} événement{{ paginator_filter.object_list.count | pluralize }} correspond{{ paginator_filter.object_list.count | pluralize:"ent" }} à la recherche.
|
|
||||||
</p>
|
|
||||||
<div>
|
<div>
|
||||||
{% for obj in paginator_filter %}
|
{% for obj in paginator_filter %}
|
||||||
{% include "agenda_culturel/single-event/event-in-flat-list-inc.html" with event=obj %}
|
{% include "agenda_culturel/single-event/event-in-flat-list-inc.html" with event=obj %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
{% include "agenda_culturel/paginator_filter.html" %}
|
{% include "agenda_culturel/paginator_filter.html" with nomax=1 %}
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
@ -2,7 +2,6 @@ import emoji
|
|||||||
from django.core.paginator import PageNotAnInteger, EmptyPage
|
from django.core.paginator import PageNotAnInteger, EmptyPage
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
|
|
||||||
from . import PaginatorFilter
|
|
||||||
from ..filters import SearchEventFilter, SimpleSearchEventFilter
|
from ..filters import SearchEventFilter, SimpleSearchEventFilter
|
||||||
from ..models import (
|
from ..models import (
|
||||||
Category,
|
Category,
|
||||||
@ -17,6 +16,8 @@ from django.db.models import Q, F, Func
|
|||||||
|
|
||||||
|
|
||||||
def event_search(request, full=False):
|
def event_search(request, full=False):
|
||||||
|
from .utils import PaginatorFilterCountless
|
||||||
|
|
||||||
categories = None
|
categories = None
|
||||||
tags = None
|
tags = None
|
||||||
places = None
|
places = None
|
||||||
@ -79,7 +80,7 @@ def event_search(request, full=False):
|
|||||||
name__icontains=request.GET["q"]
|
name__icontains=request.GET["q"]
|
||||||
)
|
)
|
||||||
|
|
||||||
paginator = PaginatorFilter(filter, 10, request)
|
paginator = PaginatorFilterCountless(filter, 10, request)
|
||||||
page = request.GET.get("page")
|
page = request.GET.get("page")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from django.core.paginator import EmptyPage, Paginator
|
from django.core.paginator import EmptyPage, Paginator
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
from django.db.models import Aggregate, FloatField
|
from django.db.models import Aggregate, FloatField
|
||||||
from ..models import Event
|
from ..models import Event
|
||||||
@ -75,3 +76,10 @@ class PaginatorFilter(Paginator):
|
|||||||
page.url_next_page = self.request.get_full_path()
|
page.url_next_page = self.request.get_full_path()
|
||||||
|
|
||||||
return page
|
return page
|
||||||
|
|
||||||
|
|
||||||
|
class PaginatorFilterCountless(PaginatorFilter):
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def count(self):
|
||||||
|
return 9999999999
|
||||||
|
Loading…
x
Reference in New Issue
Block a user