use django filters + search filter; still need adapts sub-page list views

This commit is contained in:
bkfox
2022-02-22 15:29:57 +01:00
parent e9e09104ad
commit 849a14014c
7 changed files with 145 additions and 73 deletions

View File

@ -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)

View File

@ -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)