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