]> git.parisson.com Git - mezzo.git/commitdiff
Search : count + filter by ContentType
authorEmilie <zawadzki@ircam.fr>
Fri, 7 Oct 2016 10:05:43 +0000 (12:05 +0200)
committerEmilie <zawadzki@ircam.fr>
Fri, 7 Oct 2016 10:05:43 +0000 (12:05 +0200)
app/local_settings.py
app/organization/core/templatetags/organization_tags.py
app/organization/core/urls.py
app/organization/core/views.py
app/organization/magazine/models.py
app/organization/media/models.py
app/templates/base.html
app/templates/search_results.html

index 70325834d8bcfd557b22f2d782ee0080fa1e0fa5..b1fb9bf73144f2a48e564f8274d8351d3ac0367f 100644 (file)
@@ -128,7 +128,9 @@ DASHBOARD_TAGS = ( ("mezzanine_tags.app_list",), (), ("mezzanine_tags.recent_act
 
 GRAPPELLI_ADMIN_TITLE = 'IRCAM Admin'
 
-SEARCH_MODEL_CHOICES = ()
+SEARCH_MODEL_CHOICES = None # all objects
+SEARCH_PER_PAGE = 10
+MAX_PAGING_LINKS = 10
 
 RATINGS_ACCOUNT_REQUIRED = True
 
index c0a5bd4f6b6060192b39e026cfbe2b1f05bf3f17..a1ce4cd66159ba5799e03975d45e84ed8ea59ab4 100644 (file)
@@ -1,4 +1,5 @@
 # -*- coding: utf-8 -*-
+from django.http import QueryDict
 from mezzanine.pages.models import Page
 from mezzanine.blog.models import BlogPost
 from mezzanine.template import Library
index 804c46cc64edba3f9a7b9ad6e11c6ade17cbf5ad..643d9edbd152664612e429f40065b03e2f2e7be0 100644 (file)
@@ -10,4 +10,5 @@ from mezzanine.conf import settings
 from organization.core.views import *
 
 urlpatterns = [
+     url("^search/$", CustomSearchView.as_view(), name="search"),
 ]
index 504bf76227d924f2d8a6efde33fa406b41189851..0095baca93bb9cf19a99e6e6d47de772ac77c092 100644 (file)
@@ -2,7 +2,11 @@ from django.shortcuts import render, get_object_or_404
 from django.http import Http404
 from django.views.generic.base import View
 from django.views.generic import DetailView, ListView, TemplateView
-
+from django.apps import apps
+from django.utils.translation import ugettext_lazy as _
+from django.http import QueryDict
+from mezzanine.conf import settings
+from mezzanine.utils.views import paginate
 from organization.core.models import *
 
 
@@ -16,3 +20,68 @@ class SlugMixin(object):
 # class CustomDisplayableView(SlugMixin, DetailView):
 #
 #     model = CustomDisplayable
+
+
+class CustomSearchView(TemplateView):
+
+    template_name='search_results.html'
+
+
+    def get(self, request, *args, **kwargs):
+
+        """
+        Display search results. Takes an optional "contenttype" GET parameter
+        in the form "app-name.ModelName" to limit search results to a single model.
+        """
+        context = super(CustomSearchView, self).get_context_data(**kwargs)
+        query = request.GET.get("q", "")
+        page = request.GET.get("page", 1)
+        per_page = settings.SEARCH_PER_PAGE
+        max_paging_links = settings.MAX_PAGING_LINKS
+        try:
+            parts = request.GET.get("type", "").split(".", 1)
+            search_model = apps.get_model(*parts)
+            search_model.objects.search  # Attribute check
+        except (ValueError, TypeError, LookupError, AttributeError):
+            search_model = Displayable
+            search_type = _("Everything")
+        else:
+            search_type = search_model._meta.verbose_name_plural.capitalize()
+
+        results = search_model.objects.search(query, for_user=request.user)
+
+        # count objects
+        filter_dict = dict()
+        for result in results:
+            if result.__class__.__name__ in filter_dict:
+                filter_dict[result.__class__.__name__]['count'] += 1
+            else:
+                filter_dict[result.__class__.__name__] = {'count' : 1}
+                filter_dict[result.__class__.__name__].update({'app_label' : result._meta.app_label})
+
+        # get url param
+        current_query = QueryDict(mutable=True)
+        current_query = request.GET.copy()
+
+        # generate filter url
+        for key, value in filter_dict.items():
+            current_query['type'] = value['app_label']+'.'+key
+            filter_dict[key].update({'url' : request.path+"?"+current_query.urlencode(safe='/')})
+
+        # pagination
+        paginated = paginate(results, page, per_page, max_paging_links)
+
+        # context
+        context = {"query": query, "results": paginated,
+                   "search_type": search_type}
+
+        # cancel filter url
+        if request.GET.__contains__('type'):
+            previous_query = QueryDict(mutable=True)
+            previous_query = request.GET.copy()
+            previous_query.pop('type')
+            context['cancel_filter_url'] = '?'+previous_query.urlencode(safe='/')
+
+        context['filter_dict'] = filter_dict
+        # context.update(extra_context or {})
+        return self.render_to_response(context)
index e7e355bb65c9f1a51c600751f139783edd3d9309..90dba92259bc2cee24456366fca496af67961062 100644 (file)
@@ -4,6 +4,7 @@ from django.db import models
 from django import forms
 from django.contrib.contenttypes.fields import GenericForeignKey
 from django.contrib.contenttypes.models import ContentType
+from mezzanine.core.managers import SearchableManager
 from django.utils.translation import ugettext_lazy as _
 from django.core.urlresolvers import reverse, reverse_lazy
 
@@ -13,12 +14,14 @@ from mezzanine.blog.models import BlogPost
 from organization.network.models import Department, PersonListBlock
 from organization.media.models import Audio, Video
 from organization.core.models import *
+from organization.magazine.apps import *
 
 
 class Article(BlogPost, SubTitled):
 
     department = models.ForeignKey(Department, verbose_name=_('department'), related_name='articles', limit_choices_to=dict(id__in=Department.objects.all()), blank=True, null=True, on_delete=models.SET_NULL)
     topics = models.ManyToManyField("Topic", verbose_name=_('topics'), related_name="articles", blank=True)
+    search_fields = ("title", "content")
 
     def get_absolute_url(self):
         return reverse("magazine-article-detail", kwargs={"slug": self.slug})
index f01613412c0f9ec31f1a2d947b33c50d9ac1c24c..f5d196accec735fbe10c5d6e4a5925be87d37617 100644 (file)
@@ -4,7 +4,7 @@ from pyquery import PyQuery as pq
 
 from django.db import models
 from django.utils.translation import ugettext_lazy as _
-
+from mezzanine.core.managers import SearchableManager
 from mezzanine.core.models import RichText, Displayable, Slugged
 from mezzanine.core.fields import RichTextField, OrderField, FileField
 from mezzanine.utils.models import AdminThumbMixin, upload_to
@@ -24,6 +24,9 @@ class Media(Titled):
     closed_source_url = models.URLField(_('closed source URL'), max_length=1024, blank=True)
     poster_url = models.URLField(_('poster'), max_length=1024, blank=True)
 
+    objects = SearchableManager()
+    search_fields = ("title",)
+
     class Meta:
         abstract = True
 
index bef11655a4a4f8cccae9161b73d0208d6aa1a42b..e7b55441180478b7378c207731321a1b8e674c03 100644 (file)
         </footer>
 
     </div>
-
-    {% include "includes/search_form.html" %}
+    {% search_form %}
     {% include "includes/footer_scripts.html" %}
     {% endspaceless %}
 
index 1c5b62b413ad6f7b6268376ba0ac5c58c211f2f9..cf6843a5e7787eba08fc642a3eab2d5606bcdbb1 100644 (file)
@@ -1,6 +1,6 @@
 {% extends "base.html" %}
 
-{% load i18n mezzanine_tags %}
+{% load i18n mezzanine_tags organization_tags %}
 
 {% block meta_title %}{% trans "Search Results" %}{% endblock %}
 {% block title %}{% trans "Search Results" %}{% endblock %}
             {% endif %}
         </p>
 
+        <p>
+            <h4>Filter:</h4>
+            {% for key,value in filter_dict.items %}
+                <a href="{{ value.url }}" title="{{ key }}">{{ key }} {{ value.count }}</a><br>
+            {% endfor %}
+            {% if cancel_filter_url %}
+                <a href="{{ cancel_filter_url }}" title="">Cancel filter</a>
+            {% endif %}
+        </p>
         {% for result in results.object_list %}
         {% with result.get_absolute_url as result_url %}
+
             <h5>
                 {{ forloop.counter0|add:results.start_index }})
+                 - {{ result|classname }} -
                 {% if result_url %}
                     <a href="{{ result_url }}">{{ result }}</a>
                 {% else %}