Séparation des vues recherche

This commit is contained in:
SebF 2025-04-14 17:50:59 +02:00
parent 650678b1f3
commit 001a1652bd
4 changed files with 119 additions and 103 deletions

View File

@ -90,6 +90,9 @@ from .views import (
UnknownPlaceAddView, UnknownPlaceAddView,
UnknownPlacesListView, UnknownPlacesListView,
fix_unknown_places, fix_unknown_places,
# Search
event_search,
event_search_full,
# TODO pas encore trié # TODO pas encore trié
week_view, week_view,
month_view, month_view,
@ -107,8 +110,6 @@ from .views import (
StaticContentUpdateView, StaticContentUpdateView,
MessageCreateView, MessageCreateView,
EventCreateView, EventCreateView,
event_search,
event_search_full,
update_from_source, update_from_source,
change_status_event, change_status_event,
EventDeleteView, EventDeleteView,
@ -354,6 +355,9 @@ urlpatterns = [
fix_unknown_places, fix_unknown_places,
name="fix_unknown_places", name="fix_unknown_places",
), ),
# Search
path("rechercher", event_search, name="event_search"),
path("rechercher/complet/", event_search_full, name="event_search_full"),
# TODO pas encore trié # TODO pas encore trié
path("cat:<cat>/", home, name="home_category"), path("cat:<cat>/", home, name="home_category"),
path( path(
@ -464,8 +468,6 @@ urlpatterns = [
StaticContentUpdateView.as_view(), StaticContentUpdateView.as_view(),
name="edit_static_content", name="edit_static_content",
), ),
path("rechercher", event_search, name="event_search"),
path("rechercher/complet/", event_search_full, name="event_search_full"),
path("contact", MessageCreateView.as_view(), name="contact"), path("contact", MessageCreateView.as_view(), name="contact"),
path( path(
"message/<int:pk>", "message/<int:pk>",

View File

@ -9,3 +9,4 @@ from .moderation_views import *
from .organisations_views import * from .organisations_views import *
from .places_views import * from .places_views import *
from .tag_views import * from .tag_views import *
from .search_views import *

View File

@ -14,7 +14,7 @@ from django.contrib.messages.views import SuccessMessageMixin
from django.core.cache import cache from django.core.cache import cache
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.db.models import Aggregate, FloatField from django.db.models import Aggregate, FloatField
from django.db.models import F, Func, OuterRef, Q, Subquery from django.db.models import F, OuterRef, Q, Subquery
from django.http import ( from django.http import (
HttpResponse, HttpResponse,
HttpResponseForbidden, HttpResponseForbidden,
@ -45,8 +45,6 @@ from ..celery import (
from ..filters import ( from ..filters import (
EventFilter, EventFilter,
EventFilterAdmin, EventFilterAdmin,
SearchEventFilter,
SimpleSearchEventFilter,
) )
from ..forms import ( from ..forms import (
EventForm, EventForm,
@ -69,7 +67,6 @@ from ..models import (
Place, Place,
RecurrentImport, RecurrentImport,
StaticContent, StaticContent,
remove_accents,
UserProfile, UserProfile,
) )
@ -1109,101 +1106,6 @@ def recent(request):
) )
def event_search(request, full=False):
categories = None
tags = None
places = None
organisations = None
rimports = None
qs = get_event_qs(request).order_by("-start_day")
if not request.user.is_authenticated:
qs = qs.filter(
(
Q(other_versions__isnull=True)
| Q(other_versions__representative=F("pk"))
| Q(other_versions__representative__isnull=True)
)
)
if full:
filter = SearchEventFilter(
request.GET,
queryset=qs,
request=request,
)
else:
filter = SimpleSearchEventFilter(
request.GET,
queryset=qs,
request=request,
)
if "q" in request.GET:
categories = Category.objects.filter(name__icontains=request.GET["q"])
s_q = remove_accents(request.GET["q"].lower())
tags = (
Event.objects.extra(
where=["%s ILIKE ANY (tags)"], params=[request.GET["q"]]
)
.annotate(arr_tags=Func(F("tags"), function="unnest"))
.values_list("arr_tags", flat=True)
.distinct()
)
tags = [
(
t,
emoji.demojize(remove_accents(t).lower(), delimiters=("000", "")),
)
for t in tags
]
tags = [t for t in tags if s_q == t[1]]
tags.sort(key=lambda x: x[1])
tags = [t[0] for t in tags]
places = Place.objects.filter(
Q(name__icontains=request.GET["q"])
| Q(description__icontains=request.GET["q"])
| Q(city__icontains=request.GET["q"])
)
organisations = Organisation.objects.filter(
Q(name__icontains=request.GET["q"])
| Q(description__icontains=request.GET["q"])
)
if request.user.is_authenticated:
rimports = RecurrentImport.objects.filter(
name__icontains=request.GET["q"]
)
paginator = PaginatorFilter(filter, 10, request)
page = request.GET.get("page")
try:
response = paginator.page(page)
except PageNotAnInteger:
response = paginator.page(1)
except EmptyPage:
response = paginator.page(paginator.num_pages)
return render(
request,
"agenda_culturel/search.html",
{
"filter": filter,
"categories": categories,
"tags": tags,
"places": places,
"organisations": organisations,
"rimports": rimports,
"has_results": len(request.GET) != 0
or (len(request.GET) > 1 and "page" in request.GET),
"paginator_filter": response,
"full": full,
},
)
def event_search_full(request):
return event_search(request, True)
def clear_cache(request): def clear_cache(request):
if request.method == "POST": if request.method == "POST":
cache.clear() cache.clear()

View File

@ -0,0 +1,111 @@
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,
remove_accents,
Event,
Place,
Organisation,
RecurrentImport,
)
from ..views import get_event_qs
from django.db.models import Q, F, Func
def event_search(request, full=False):
categories = None
tags = None
places = None
organisations = None
rimports = None
qs = get_event_qs(request).order_by("-start_day")
if not request.user.is_authenticated:
qs = qs.filter(
(
Q(other_versions__isnull=True)
| Q(other_versions__representative=F("pk"))
| Q(other_versions__representative__isnull=True)
)
)
if full:
filter = SearchEventFilter(
request.GET,
queryset=qs,
request=request,
)
else:
filter = SimpleSearchEventFilter(
request.GET,
queryset=qs,
request=request,
)
if "q" in request.GET:
categories = Category.objects.filter(name__icontains=request.GET["q"])
s_q = remove_accents(request.GET["q"].lower())
tags = (
Event.objects.extra(
where=["%s ILIKE ANY (tags)"], params=[request.GET["q"]]
)
.annotate(arr_tags=Func(F("tags"), function="unnest"))
.values_list("arr_tags", flat=True)
.distinct()
)
tags = [
(
t,
emoji.demojize(remove_accents(t).lower(), delimiters=("000", "")),
)
for t in tags
]
tags = [t for t in tags if s_q == t[1]]
tags.sort(key=lambda x: x[1])
tags = [t[0] for t in tags]
places = Place.objects.filter(
Q(name__icontains=request.GET["q"])
| Q(description__icontains=request.GET["q"])
| Q(city__icontains=request.GET["q"])
)
organisations = Organisation.objects.filter(
Q(name__icontains=request.GET["q"])
| Q(description__icontains=request.GET["q"])
)
if request.user.is_authenticated:
rimports = RecurrentImport.objects.filter(
name__icontains=request.GET["q"]
)
paginator = PaginatorFilter(filter, 10, request)
page = request.GET.get("page")
try:
response = paginator.page(page)
except PageNotAnInteger:
response = paginator.page(1)
except EmptyPage:
response = paginator.page(paginator.num_pages)
return render(
request,
"agenda_culturel/search.html",
{
"filter": filter,
"categories": categories,
"tags": tags,
"places": places,
"organisations": organisations,
"rimports": rimports,
"has_results": len(request.GET) != 0
or (len(request.GET) > 1 and "page" in request.GET),
"paginator_filter": response,
"full": full,
},
)
def event_search_full(request):
return event_search(request, True)