mirror of https://github.com/interlegis/sapl.git
Leandro Roberto
6 years ago
4 changed files with 316 additions and 270 deletions
@ -1,231 +1,65 @@ |
|||||
import logging |
from django.db.models.fields.files import FileField |
||||
|
from django.template.defaultfilters import capfirst |
||||
from django.db.models import Q |
import django_filters |
||||
from django.forms.fields import CharField, MultiValueField |
from django_filters.filters import CharFilter, NumberFilter |
||||
from django.forms.widgets import MultiWidget, TextInput |
|
||||
from django.utils import timezone |
|
||||
from django.utils.translation import ugettext_lazy as _ |
|
||||
from django_filters.filters import CharFilter, ModelChoiceFilter, DateFilter |
|
||||
from django_filters.rest_framework.filterset import FilterSet |
from django_filters.rest_framework.filterset import FilterSet |
||||
from rest_framework import serializers |
from django_filters.utils import resolve_field |
||||
|
from sapl.sessao.models import SessaoPlenaria |
||||
from sapl.base.models import Autor, TipoAutor |
|
||||
from sapl.parlamentares.models import Legislatura |
|
||||
from sapl.utils import generic_relations_for_model |
|
||||
|
|
||||
|
|
||||
class SaplGenericRelationSearchFilterSet(FilterSet): |
|
||||
q = CharFilter(method='filter_q') |
|
||||
|
|
||||
def filter_q(self, queryset, name, value): |
|
||||
|
|
||||
query = value.split(' ') |
|
||||
if query: |
|
||||
q = Q() |
|
||||
for qtext in query: |
|
||||
if not qtext: |
|
||||
continue |
|
||||
q_fs = Q(nome__icontains=qtext) |
|
||||
|
|
||||
order_by = [] |
|
||||
|
|
||||
for gr in generic_relations_for_model(self._meta.model): |
|
||||
sgr = gr[1] |
|
||||
for item in sgr: |
|
||||
if item.related_model != self._meta.model: |
|
||||
|
|
||||
continue |
|
||||
flag_order_by = True |
|
||||
for field in item.fields_search: |
|
||||
if flag_order_by: |
|
||||
flag_order_by = False |
|
||||
order_by.append('%s__%s' % ( |
|
||||
item.related_query_name(), |
|
||||
field[0]) |
|
||||
) |
|
||||
# if len(field) == 3 and field[2](qtext) is not |
|
||||
# None: |
|
||||
q_fs = q_fs | Q(**{'%s__%s%s' % ( |
|
||||
item.related_query_name(), |
|
||||
field[0], |
|
||||
field[1]): qtext if len(field) == 2 |
|
||||
else field[2](qtext)}) |
|
||||
|
|
||||
q = q & q_fs |
|
||||
|
|
||||
if q: |
|
||||
queryset = queryset.filter(q).order_by(*order_by) |
|
||||
|
|
||||
return queryset |
|
||||
|
|
||||
|
|
||||
class SearchForFieldWidget(MultiWidget): |
|
||||
|
|
||||
def decompress(self, value): |
|
||||
if value is None: |
|
||||
return [None, None] |
|
||||
return value |
|
||||
|
|
||||
def __init__(self, attrs=None): |
class SaplFilterSetMixin(FilterSet): |
||||
widgets = (TextInput, TextInput) |
|
||||
MultiWidget.__init__(self, widgets, attrs) |
|
||||
|
|
||||
|
o = CharFilter(method='filter_o') |
||||
class SearchForFieldField(MultiValueField): |
|
||||
widget = SearchForFieldWidget |
|
||||
|
|
||||
def __init__(self, *args, **kwargs): |
|
||||
fields = ( |
|
||||
CharField(), |
|
||||
CharField()) |
|
||||
super(SearchForFieldField, self).__init__(fields, *args, **kwargs) |
|
||||
|
|
||||
def compress(self, parameters): |
|
||||
if parameters: |
|
||||
return parameters |
|
||||
return None |
|
||||
|
|
||||
|
|
||||
class SearchForFieldFilter(CharFilter): |
|
||||
field_class = SearchForFieldField |
|
||||
|
|
||||
|
|
||||
class AutorChoiceFilterSet(SaplGenericRelationSearchFilterSet): |
|
||||
q = CharFilter(method='filter_q') |
|
||||
tipo = ModelChoiceFilter(queryset=TipoAutor.objects.all()) |
|
||||
|
|
||||
class Meta: |
class Meta: |
||||
model = Autor |
fields = '__all__' |
||||
fields = ['q', |
filter_overrides = { |
||||
'tipo', |
FileField: { |
||||
'nome', ] |
'filter_class': django_filters.CharFilter, |
||||
|
'extra': lambda f: { |
||||
def filter_q(self, queryset, name, value): |
'lookup_expr': 'exact', |
||||
return super().filter_q( |
}, |
||||
queryset, name, value).distinct('nome').order_by('nome') |
}, |
||||
|
} |
||||
|
|
||||
class AutorSearchForFieldFilterSet(AutorChoiceFilterSet): |
def filter_o(self, queryset, name, value): |
||||
q = SearchForFieldFilter(method='filter_q') |
|
||||
|
|
||||
class Meta(AutorChoiceFilterSet.Meta): |
|
||||
pass |
|
||||
|
|
||||
def filter_q(self, queryset, name, value): |
|
||||
|
|
||||
value[0] = value[0].split(',') |
|
||||
value[1] = value[1].split(',') |
|
||||
|
|
||||
params = {} |
|
||||
for key, v in list(zip(value[0], value[1])): |
|
||||
if v in ['True', 'False']: |
|
||||
v = '1' if v == 'True' else '0' |
|
||||
params[key] = v |
|
||||
return queryset.filter(**params).distinct('nome').order_by('nome') |
|
||||
|
|
||||
|
|
||||
class AutoresPossiveisFilterSet(FilterSet): |
|
||||
logger = logging.getLogger(__name__) |
|
||||
data_relativa = DateFilter(method='filter_data_relativa') |
|
||||
tipo = CharFilter(method='filter_tipo') |
|
||||
|
|
||||
class Meta: |
|
||||
model = Autor |
|
||||
fields = ['data_relativa', 'tipo', ] |
|
||||
|
|
||||
def filter_data_relativa(self, queryset, name, value): |
|
||||
return queryset |
|
||||
|
|
||||
def filter_tipo(self, queryset, name, value): |
|
||||
|
|
||||
try: |
try: |
||||
self.logger.debug( |
return queryset.order_by( |
||||
"Tentando obter TipoAutor correspondente à pk {}.".format(value)) |
*map(str.strip, value.split(','))) |
||||
tipo = TipoAutor.objects.get(pk=value) |
|
||||
except: |
except: |
||||
self.logger.error("TipoAutor(pk={}) inexistente.".format(value)) |
return queryset |
||||
raise serializers.ValidationError(_('Tipo de Autor inexistente.')) |
|
||||
|
@classmethod |
||||
qs = queryset.filter(tipo=tipo) |
def filter_for_field(cls, f, name, lookup_expr='exact'): |
||||
|
# Redefine método estático para ignorar filtro para |
||||
return qs |
# fields que não possuam lookup_expr informado |
||||
|
f, lookup_type = resolve_field(f, lookup_expr) |
||||
@property |
|
||||
def qs(self): |
default = { |
||||
qs = super().qs |
'field_name': name, |
||||
|
'label': capfirst(f.verbose_name), |
||||
data_relativa = self.form.cleaned_data['data_relativa'] \ |
'lookup_expr': lookup_expr |
||||
if 'data_relativa' in self.form.cleaned_data else None |
} |
||||
|
|
||||
tipo = self.form.cleaned_data['tipo'] \ |
filter_class, params = cls.filter_for_lookup( |
||||
if 'tipo' in self.form.cleaned_data else None |
f, lookup_type) |
||||
|
default.update(params) |
||||
if not tipo: |
if filter_class is not None: |
||||
return qs |
return filter_class(**default) |
||||
|
return None |
||||
tipo = TipoAutor.objects.get(pk=tipo) |
|
||||
if not tipo.content_type: |
|
||||
return qs |
|
||||
|
|
||||
filter_for_model = 'filter_%s' % tipo.content_type.model |
|
||||
|
|
||||
if not hasattr(self, filter_for_model): |
|
||||
return qs |
|
||||
|
|
||||
if not data_relativa: |
|
||||
data_relativa = timezone.now() |
|
||||
|
|
||||
return getattr(self, filter_for_model)(qs, data_relativa).distinct() |
|
||||
|
|
||||
def filter_parlamentar(self, queryset, data_relativa): |
|
||||
# não leva em conta afastamentos |
|
||||
legislatura_relativa = Legislatura.objects.filter( |
|
||||
data_inicio__lte=data_relativa, |
|
||||
data_fim__gte=data_relativa).first() |
|
||||
|
|
||||
q = Q( |
|
||||
parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, |
|
||||
parlamentar_set__mandato__data_fim_mandato__isnull=True) | Q( |
|
||||
parlamentar_set__mandato__data_inicio_mandato__lte=data_relativa, |
|
||||
parlamentar_set__mandato__data_fim_mandato__gte=data_relativa) |
|
||||
|
|
||||
if legislatura_relativa.atual(): |
|
||||
q = q & Q(parlamentar_set__ativo=True) |
|
||||
|
|
||||
return queryset.filter(q) |
|
||||
|
|
||||
def filter_comissao(self, queryset, data_relativa): |
|
||||
return queryset.filter( |
|
||||
Q(comissao_set__data_extincao__isnull=True, |
|
||||
comissao_set__data_fim_comissao__isnull=True) | |
|
||||
Q(comissao_set__data_extincao__gte=data_relativa, |
|
||||
comissao_set__data_fim_comissao__isnull=True) | |
|
||||
Q(comissao_set__data_extincao__gte=data_relativa, |
|
||||
comissao_set__data_fim_comissao__isnull=True) | |
|
||||
Q(comissao_set__data_extincao__isnull=True, |
|
||||
comissao_set__data_fim_comissao__gte=data_relativa) | |
|
||||
Q(comissao_set__data_extincao__gte=data_relativa, |
|
||||
comissao_set__data_fim_comissao__gte=data_relativa), |
|
||||
comissao_set__data_criacao__lte=data_relativa) |
|
||||
|
|
||||
def filter_frente(self, queryset, data_relativa): |
class SessaoPlenariaFilterSet(SaplFilterSetMixin): |
||||
return queryset.filter( |
year = NumberFilter(method='filter_year') |
||||
Q(frente_set__data_extincao__isnull=True) | |
month = NumberFilter(method='filter_month') |
||||
Q(frente_set__data_extincao__gte=data_relativa), |
|
||||
frente_set__data_criacao__lte=data_relativa) |
|
||||
|
|
||||
def filter_bancada(self, queryset, data_relativa): |
class Meta(SaplFilterSetMixin.Meta): |
||||
return queryset.filter( |
model = SessaoPlenaria |
||||
Q(bancada_set__data_extincao__isnull=True) | |
|
||||
Q(bancada_set__data_extincao__gte=data_relativa), |
|
||||
bancada_set__data_criacao__lte=data_relativa) |
|
||||
|
|
||||
def filter_bloco(self, queryset, data_relativa): |
def filter_year(self, queryset, name, value): |
||||
return queryset.filter( |
qs = queryset.filter(data_inicio__year=value) |
||||
Q(bloco_set__data_extincao__isnull=True) | |
return qs |
||||
Q(bloco_set__data_extincao__gte=data_relativa), |
|
||||
bloco_set__data_criacao__lte=data_relativa) |
|
||||
|
|
||||
def filter_orgao(self, queryset, data_relativa): |
def filter_month(self, queryset, name, value): |
||||
# na implementação, não havia regras a implementar para orgao |
qs = queryset.filter(data_inicio__month=value) |
||||
return queryset |
return qs |
||||
|
Loading…
Reference in new issue