diff --git a/aircox/filters.py b/aircox/filters.py new file mode 100644 index 0000000..39fa212 --- /dev/null +++ b/aircox/filters.py @@ -0,0 +1,26 @@ +from django.utils.translation import gettext_lazy as _ +import django_filters as filters + +from .models import Page, Episode + + +class PageFilters(filters.FilterSet): + q = filters.CharFilter(method='search_filter', label=_('Search')) + + class Meta: + model = Page + fields = { + 'category__id': ['in'], + 'pub_date': ['exact', 'gte', 'lte'], + } + + def search_filter(self, queryset, name, value): + return queryset.search(value) + + +class EpisodeFilters(PageFilters): + class Meta: + model = Episode + fields = { + } + diff --git a/aircox/models/page.py b/aircox/models/page.py index 19b4a82..b1c5123 100644 --- a/aircox/models/page.py +++ b/aircox/models/page.py @@ -53,6 +53,11 @@ class PageQuerySet(InheritanceQuerySet): return self.filter(parent=parent) if id is None else \ self.filter(parent__id=id) + def search(self, q, search_content=True): + if search_content: + return self.filter(models.Q(title__icontains=q) | models.Q(content__icontains=q)) + return self.filter(title__icontains=q) + class BasePage(models.Model): """ Base class for publishable content """ diff --git a/aircox/templates/aircox/base.html b/aircox/templates/aircox/base.html index 0b489f1..955e801 100644 --- a/aircox/templates/aircox/base.html +++ b/aircox/templates/aircox/base.html @@ -57,6 +57,19 @@ Usefull context: {% endblock %} diff --git a/aircox/templates/aircox/basepage_list.html b/aircox/templates/aircox/basepage_list.html index 43656d8..61b09fd 100644 --- a/aircox/templates/aircox/basepage_list.html +++ b/aircox/templates/aircox/basepage_list.html @@ -24,48 +24,7 @@ {% block main %}{{ block.super }} -{% block before_list %} -{% if filters %} -
-
- {% block filters %} - {% for label, name, choices in filters %} -
-
- -
-
-
-
- {% for label, value, checked in choices %} - - {% endfor %} -
-
-
-
- {% endfor %} - {% endblock %} -
-
-
-
- -
- -
-
-
-{% endif %} - -{% endblock %} +{% block before_list %}{% endblock %}
{% block pages_list %} diff --git a/aircox/templates/aircox/page_list.html b/aircox/templates/aircox/page_list.html index 32ae43b..1d1945e 100644 --- a/aircox/templates/aircox/page_list.html +++ b/aircox/templates/aircox/page_list.html @@ -2,3 +2,62 @@ {% comment %}Display a list of Pages{% endcomment %} {% load i18n aircox %} +{% block before_list %} +{{ block.super }} + +{% if view.has_filters %} +
+
+ {% block filters %} +
+
+ +
+
+
+
+ + + + +
+
+
+
+
+
+ +
+
+
+
+ {% for label, value in categories %} + + {% endfor %} +
+
+
+
+ {% endblock %} +
+
+
+
+ +
+ +
+
+
+{% endif %} +{% endblock %} + diff --git a/aircox/views/mixins.py b/aircox/views/mixins.py index 29d11be..c74235e 100644 --- a/aircox/views/mixins.py +++ b/aircox/views/mixins.py @@ -80,3 +80,31 @@ class AttachedToMixin: .published().first() return super().get_page() + +class FiltersMixin: + """ Mixin integrating Django filters' filter set """ + filterset = None + filterset_class = None + + def get_filterset(self, data, query): + return self.filterset_class(data, query) + + def get_queryset(self): + query = super().get_queryset() + if self.filterset_class: + self.filterset = self.get_filterset(self.request.GET.copy(), query) + return self.filterset.qs + return query + + def get_context_data(self, **kwargs): + filterset = kwargs.setdefault('filterset', self.filterset) + if filterset.is_valid(): + kwargs['filterset_data'] = filterset.form.cleaned_data + else: + kwargs['filterset_data'] = {} + + params = self.request.GET.copy() + kwargs['get_params'] = params.pop('page', True) and params + return super().get_context_data(**kwargs) + + diff --git a/aircox/views/page.py b/aircox/views/page.py index edd9215..4699287 100644 --- a/aircox/views/page.py +++ b/aircox/views/page.py @@ -5,11 +5,12 @@ from django.views.generic import DetailView, ListView from honeypot.decorators import check_honeypot +from ..filters import PageFilters from ..forms import CommentForm from ..models import Category, Comment from ..utils import Redirect from .base import BaseView -from .mixins import AttachedToMixin, ParentMixin +from .mixins import AttachedToMixin, FiltersMixin, ParentMixin __all__ = ['BasePageListView', 'BasePageDetailView', 'PageDetailView', 'PageListView'] @@ -71,50 +72,32 @@ class BasePageDetailView(BaseView, DetailView): return self.object -class PageListView(BasePageListView): +class PageListView(FiltersMixin, BasePageListView): """ Page list view. """ + filterset_class = PageFilters template_name = None has_filters = True categories = None filters = None - def get(self, *args, **kwargs): - self.categories = set(self.request.GET.getlist('categories')) - self.filters = set(self.request.GET.getlist('filters')) - return super().get(*args, **kwargs) - def get_template_names(self): return super().get_template_names() + ['aircox/page_list.html'] + def get_filterset(self, data, query): + # FIXME: not the most efficient, cause join then split (in django filters) + data['category__id__in'] = ','.join(data.getlist('category__id__in')) + return super().get_filterset(data, query) + def get_queryset(self): qs = super().get_queryset().select_related('category') \ .order_by('-pub_date') - - # category can be filtered based on request.GET['categories'] - # (by id) - if self.categories: - qs = qs.filter(category__slug__in=self.categories) return qs - def get_filters(self): - categories = self.model.objects.published() \ - .filter(category__isnull=False) \ - .values_list('category', flat=True) - categories = [ (c.title, c.slug, c.slug in self.categories) - for c in Category.objects.filter(id__in=categories) ] - return ( - (_('Categories'), 'categories', categories), - ) - def get_context_data(self, **kwargs): - if not 'filters' in kwargs: - filters = self.get_filters() - for label, fieldName, choices in filters: - if choices: - kwargs['filters'] = filters - break; - else: - kwargs['filters'] = tuple() + kwargs['categories'] = self.model.objects.published() \ + .filter(category__isnull=False) \ + .values_list('category__title', 'category__id') \ + .distinct() return super().get_context_data(**kwargs) @@ -151,6 +134,5 @@ class PageDetailView(BasePageDetailView): comment = form.save(commit=False) comment.page = self.object comment.save() - return self.get(request, *args, **kwargs)