"""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() state__in = filters.CharFilter(method='by_states_list') 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 by_states_list(self, queryset, name, value): states = value.split('__') return queryset.filter(state__in=states) 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}')