Browse Source

isola filtro mixin para adição de lookups

pull/3445/head
Leandro Roberto 4 years ago
parent
commit
49585e3186
  1. 6
      sapl/api/core/__init__.py
  2. 56
      sapl/api/core/filters.py
  3. 49
      sapl/api/forms.py

6
sapl/api/core/__init__.py

@ -20,7 +20,7 @@ from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet from rest_framework.viewsets import ModelViewSet
from sapl.api.forms import SaplFilterSetMixin from sapl.api.core.filters import SaplFilterSetMixin
from sapl.api.permissions import SaplModelPermissions from sapl.api.permissions import SaplModelPermissions
from sapl.api.serializers import ChoiceSerializer, ParlamentarSerializer,\ from sapl.api.serializers import ChoiceSerializer, ParlamentarSerializer,\
ParlamentarEditSerializer, ParlamentarResumeSerializer ParlamentarEditSerializer, ParlamentarResumeSerializer
@ -56,6 +56,7 @@ class SaplApiViewSetConstrutor():
# Carrega todas as classes de sapl.api.serializers que possuam # Carrega todas as classes de sapl.api.serializers que possuam
# "Serializer" como Sufixo. # "Serializer" como Sufixo.
serializers_classes = inspect.getmembers(serializers) serializers_classes = inspect.getmembers(serializers)
serializers_classes = {i[0]: i[1] for i in filter( serializers_classes = {i[0]: i[1] for i in filter(
lambda x: x[0].endswith('Serializer'), lambda x: x[0].endswith('Serializer'),
serializers_classes serializers_classes
@ -82,7 +83,8 @@ class SaplApiViewSetConstrutor():
serializer_name, rest_serializers.ModelSerializer) serializer_name, rest_serializers.ModelSerializer)
# Caso Exista, pega a classe sapl.api.forms.{model}FilterSet # Caso Exista, pega a classe sapl.api.forms.{model}FilterSet
# ou utiliza a base definida em sapl.forms.SaplFilterSetMixin # ou utiliza a base definida em
# sapl.api.core.filters.SaplFilterSetMixin
filter_name = f'{object_name}FilterSet' filter_name = f'{object_name}FilterSet'
_filterset_class = filters_classes.get( _filterset_class = filters_classes.get(
filter_name, SaplFilterSetMixin) filter_name, SaplFilterSetMixin)

56
sapl/api/core/filters.py

@ -0,0 +1,56 @@
from django.db.models.fields import CharField
from django.db.models.fields.files import FileField
from django.template.defaultfilters import capfirst
import django_filters
from django_filters.filters import CharFilter
from django_filters.rest_framework.filterset import FilterSet
from django_filters.utils import resolve_field
class SaplFilterSetMixin(FilterSet):
o = CharFilter(method='filter_o')
class Meta:
fields = '__all__'
filter_overrides = {
CharField: {
'filter_class': django_filters.CharFilter,
'extra': lambda f: {
'lookup_expr': ['exact', 'icontains']
}
},
FileField: {
'filter_class': django_filters.CharFilter,
'extra': lambda f: {
'lookup_expr': 'exact',
},
},
}
def filter_o(self, queryset, name, value):
try:
return queryset.order_by(
*map(str.strip, value.split(',')))
except:
return queryset
@classmethod
def filter_for_field(cls, f, name, lookup_expr='exact'):
# Redefine método estático para ignorar filtro para
# fields que não possuam lookup_expr informado
f, lookup_type = resolve_field(f, lookup_expr)
default = {
'field_name': name,
'label': capfirst(f.verbose_name),
'lookup_expr': lookup_expr
}
filter_class, params = cls.filter_for_lookup(
f, lookup_type)
default.update(params)
if filter_class is not None:
return filter_class(**default)
return None

49
sapl/api/forms.py

@ -1,52 +1,9 @@
from django.db.models.fields.files import FileField
from django.template.defaultfilters import capfirst
import django_filters
from django_filters.filters import CharFilter, NumberFilter
from django_filters.rest_framework.filterset import FilterSet
from django_filters.utils import resolve_field
from sapl.sessao.models import SessaoPlenaria
class SaplFilterSetMixin(FilterSet):
o = CharFilter(method='filter_o')
class Meta:
fields = '__all__'
filter_overrides = {
FileField: {
'filter_class': django_filters.CharFilter,
'extra': lambda f: {
'lookup_expr': 'exact',
},
},
}
def filter_o(self, queryset, name, value): from django_filters.filters import NumberFilter
try:
return queryset.order_by(
*map(str.strip, value.split(',')))
except:
return queryset
@classmethod from sapl.api.core.filters import SaplFilterSetMixin
def filter_for_field(cls, f, name, lookup_expr='exact'): from sapl.sessao.models import SessaoPlenaria
# Redefine método estático para ignorar filtro para
# fields que não possuam lookup_expr informado
f, lookup_type = resolve_field(f, lookup_expr)
default = {
'field_name': name,
'label': capfirst(f.verbose_name),
'lookup_expr': lookup_expr
}
filter_class, params = cls.filter_for_lookup(
f, lookup_type)
default.update(params)
if filter_class is not None:
return filter_class(**default)
return None
class SessaoPlenariaFilterSet(SaplFilterSetMixin): class SessaoPlenariaFilterSet(SaplFilterSetMixin):

Loading…
Cancel
Save