gault-millau/apps/news/filters.py
2020-01-22 21:47:21 +03:00

89 lines
2.9 KiB
Python

"""Filters from application News"""
from django.core.validators import EMPTY_VALUES
from django.utils.translation import gettext_lazy as _
from django_filters import rest_framework as filters
from rest_framework.serializers import ValidationError
from news import models
class NewsListFilterSet(filters.FilterSet):
"""FilterSet for News list"""
is_highlighted = filters.BooleanFilter()
title = filters.CharFilter(method='by_title')
tag_group = filters.ChoiceFilter(
choices=(
(models.News.RECIPES_TAG_VALUE, _('Recipes')),
),
method='by_tag_group'
)
tag_value__exclude = filters.CharFilter(method='exclude_tags')
tag_value__in = filters.CharFilter(method='in_tags')
type = filters.CharFilter(method='by_type')
state = filters.NumberFilter()
SORT_BY_CREATED_CHOICE = "created"
SORT_BY_START_CHOICE = "start"
SORT_BY_CHOICES = (
(SORT_BY_CREATED_CHOICE, "created"),
(SORT_BY_START_CHOICE, "start"),
)
sort_by = filters.ChoiceFilter(method='sort_by_field', choices=SORT_BY_CHOICES)
search = filters.CharFilter(method='search_news')
class Meta:
"""Meta class"""
model = models.News
fields = (
'title',
'is_highlighted',
'tag_group',
'tag_value__exclude',
'tag_value__in',
'state',
'sort_by',
'search',
)
def search_news(self, queryset, name, value):
if value not in EMPTY_VALUES:
if len(value) < 3:
raise ValidationError({'detail': _('Type at least 3 characters to search please.')})
return queryset.es_search(value, relevance_order='ordering' not in self.request.query_params)
return queryset
def in_tags(self, queryset, name, value):
tags = value.split('__')
return queryset.filter(tags__value__in=tags)
def exclude_tags(self, queryset, name, value):
tags = value.split('__')
return queryset.exclude(tags__value__in=tags)
def by_tag_group(self, queryset, name, value):
if value == models.News.RECIPES_TAG_VALUE:
queryset = queryset.recipe_news()
return queryset
def by_title(self, queryset, name, value):
"""Crappy search by title according to locale"""
if value:
locale = self.request.locale
filters = {f'{name}__{locale}__icontains': value}
return queryset.filter(**filters)
else:
return queryset
def by_type(self, queryset, name, value):
if value:
return queryset.filter(news_type__name=value)
else:
return queryset
def sort_by_field(self, queryset, name, value):
if value == self.SORT_BY_START_CHOICE:
return queryset.order_by('-publication_date', '-publication_time')
return queryset.order_by(f'-{value}')