89 lines
2.9 KiB
Python
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}')
|