]> git.0d.be Git - panikweb.git/commitdiff
add postgresql fts search view for newsitems
authorFrédéric Péters <fpeters@0d.be>
Thu, 23 Mar 2023 13:24:08 +0000 (14:24 +0100)
committerFrédéric Péters <fpeters@0d.be>
Thu, 23 Mar 2023 13:24:47 +0000 (14:24 +0100)
panikweb/search.py
panikweb/static/css/_specifics.scss
panikweb/templates/news/search.html [new file with mode: 0644]
panikweb/urls.py

index 6c0ae69cde67331e10513b5cb111903008fe04c2..eddfaf6fd02d6a9fcf61af38fa4a7c73e2aaa81b 100644 (file)
@@ -6,7 +6,7 @@ from django.utils.text import slugify
 from django.utils.translation import gettext_lazy as _
 from django.views.decorators.csrf import csrf_exempt
 from django.views.generic.list import ListView
-from emissions.models import Emission, Episode, Format, NewsItem, SoundFile
+from emissions.models import Emission, Episode, Format, NewsCategory, NewsItem, SoundFile
 from haystack.backends import EmptyResults
 from haystack.constants import DJANGO_CT, DJANGO_ID, ID
 from haystack.query import RelatedSearchQuerySet, SearchQuerySet
@@ -333,3 +333,34 @@ class GlobalSearchView(ListView):
 
 
 global_search = GlobalSearchView.as_view()
+
+
+class NewsItemSearchView(ListView):
+    template_name = 'news/search.html'
+    paginate_by = 20
+
+    def get_queryset(self):
+        qs = NewsItem.objects.all()
+        if self.request.GET.get('category'):
+            qs = qs.filter(category__slug=self.request.GET.get('category'))
+        if self.request.GET.get('q'):
+            vector = (
+                SearchVector('title', config=settings.FTS_DICTIONARY_CONFIG, weight='A')
+                + SearchVector('text', config=settings.FTS_DICTIONARY_CONFIG, weight='B')
+                + SearchVector('emission__title', config=settings.FTS_DICTIONARY_CONFIG, weight='C')
+            )
+            query = SearchQuery(self.request.GET.get('q', ''), config=settings.FTS_DICTIONARY_CONFIG)
+            qs = qs.annotate(rank=SearchRank(vector, query)).filter(rank__gte=0.1).order_by('-rank')
+        qs = qs.select_related()
+        qs = qs.order_by('-date')
+        return qs
+
+    def get_context_data(self, **kwargs):
+        context = super().get_context_data(**kwargs)
+        context['categories'] = NewsCategory.objects.all()
+        context['selected_category'] = self.request.GET.get('category')
+        context['query'] = self.request.GET.get('q')
+        return context
+
+
+newsitems_search = NewsItemSearchView.as_view()
index 171581d3bbca9c34e128df20053f8be5aba6ad7b..81d667f91c61eb34fc7f47a7d35a8a28a308792f 100644 (file)
@@ -2415,6 +2415,7 @@ div#loading-page {
 }
 
 #search-form {
+       .newsitems-categories,
        .soundfiles-formats {
                margin: 2em 0;
                display: flex;
diff --git a/panikweb/templates/news/search.html b/panikweb/templates/news/search.html
new file mode 100644 (file)
index 0000000..aa0bf1a
--- /dev/null
@@ -0,0 +1,78 @@
+{% extends "news.html" %}
+{% load gadjo paniktags i18n %}
+{% block title %}{% trans 'News' %} - Archives{% endblock %}
+{% block nav %}{% endblock %}
+
+{% block main %}
+    <form method="get" action="." class="padded center" id="search-form">
+      <div class="big">
+        <input type="text" name="q" id="id_q" value="{{ request.GET.q|default:"" }}">
+        <button class="icon-search"><span class="sr-only">{% trans "Search" %}</span></button>
+      </div>
+
+      <div class="newsitems-categories">
+      {% for category in categories %}
+      <label><input type="radio" name="category" value="{{category.slug}}" {% if request.GET.category == category.slug %}checked{% endif %}><span>{{ category.title }}</span></label>
+      {% endfor %}
+      </div>
+    </form>
+    <script>
+document.querySelectorAll('.newsitems-categories input').forEach(function(input) {
+  input.was_checked = input.checked;
+  input.addEventListener('click', function(e) {
+    if (input.was_checked) {
+      input.checked = false;
+      input.was_checked = false;
+    } else {
+      document.querySelectorAll('.newsitems-categories input').forEach(function(input) { input.was_checked = false; });
+      input.was_checked = true;
+    }
+    $(document.getElementById('search-form')).trigger('submit');
+  });
+});
+    </script>
+
+<div class="wrapper">
+
+{% if not object_list %}
+       <div class="big error padded center">Manque de pot, pas de résultats à cette recherche !</div>
+{% else %}
+
+{% if page_obj.has_previous %}
+<div class="previous-page cf">
+<a class="button big left" href="{% querystring "page"=page_obj.previous_page_number %}">&laquo; Résultats précédénts</a>
+</div>
+{% endif %}
+
+       <div id="Emission-container" class="emission">
+               {% if page_obj.object_list %}
+                       {% regroup page_obj.object_list by date|date:"F Y"|capfirst as month_list %}
+                       <div>
+                       {% for month in month_list %}
+                               <div class="monthGroup {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}">
+                               <div class="legend button" onclick="$('#{{ month.grouper|slugify }}').toggle();"
+                                               >&gt; {{ month.grouper }}</div>
+                                       <ul class="custom main-flex list" id="{{ month.grouper|slugify }}">
+                                       {% for result in month.list %}
+                                               <li>{% with result as content %}{% news_inline %}{% endwith %}</li>
+                                       {% endfor %}
+                                       </ul>
+                                       </div>
+                               {% endfor %}
+                               </div>
+               {% endif %}
+       </div>
+
+
+
+{% if page_obj.has_next %}
+<div class="next-page cf">
+<a class="button big right" href="{% querystring "page"=page_obj.next_page_number %}">Résultats suivants &raquo;</a>
+</div>
+{% endif %}
+
+{% endif %}
+
+</div>
+
+{% endblock %}
index f5de307491a91916255b0924231ba0bd884a3ec6..6885b7a9c0154e415472a257f355d39f9d0e8d99 100644 (file)
@@ -76,7 +76,11 @@ urlpatterns = [
     re_path(
         r'^%sagenda$' % settings.NEWSITEMS_PREFIX, RedirectView.as_view(pattern_name='agenda', permanent=True)
     ),
-    re_path(r'^%sarchives/$' % settings.NEWSITEMS_PREFIX, search.newsArchives, name='newsArchives'),
+    re_path(
+        r'^%sarchives/$' % settings.NEWSITEMS_PREFIX,
+        search.newsArchives if settings.USE_HAYSTACK else search.newsitems_search,
+        name='newsArchives',
+    ),
     re_path(r'^%s(?P<slug>[\w,-]+)$' % settings.NEWSITEMS_PREFIX, views.newsitemview, name='newsitem-view'),
     path('party', views.party, name='party'),
     path('recherche/', search.view if settings.USE_HAYSTACK else search.global_search, name='search'),