mirror of https://github.com/interlegis/sapl.git
Browse Source
* isola filtro mixin para adição de lookups * refatora api para filtrar com lookupspull/3446/head
Leandro Roberto Silva
3 years ago
committed by
GitHub
3 changed files with 112 additions and 62 deletions
@ -0,0 +1,105 @@ |
|||
|
|||
from collections import OrderedDict |
|||
|
|||
from django.conf import settings |
|||
from django.db.models.fields import DateTimeField, DateField |
|||
from django.db.models.fields.files import FileField |
|||
from django.template.defaultfilters import capfirst |
|||
import django_filters |
|||
from django_filters.constants import ALL_FIELDS |
|||
from django_filters.filters import CharFilter |
|||
from django_filters.filterset import BaseFilterSet, FilterSetMetaclass, \ |
|||
FilterSet |
|||
from django_filters.utils import resolve_field, get_all_model_fields |
|||
|
|||
|
|||
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): |
|||
try: |
|||
return queryset.order_by( |
|||
*map(str.strip, value.split(','))) |
|||
except: |
|||
return queryset |
|||
|
|||
@classmethod |
|||
def get_fields(cls): |
|||
model = cls._meta.model |
|||
fields_model = get_all_model_fields(model) |
|||
fields_filter = cls._meta.fields |
|||
exclude = cls._meta.exclude |
|||
|
|||
if exclude is not None and fields_filter is None: |
|||
fields_filter = ALL_FIELDS |
|||
|
|||
fields = fields_filter if isinstance(fields_filter, dict) else {} |
|||
if not isinstance(fields_filter, (dict, str)): |
|||
for f in fields_filter: |
|||
fields[f] = ['exact'] |
|||
|
|||
for f_str in fields_model: |
|||
if f_str not in fields: |
|||
f = model._meta.get_field(f_str) |
|||
fields[f_str] = [] |
|||
|
|||
def get_keys_lookups(cl, sub_f): |
|||
r = [] |
|||
for lk, lv in cl.items(): |
|||
if lk == 'contained_by': |
|||
continue |
|||
sflk = f'{sub_f}{"__" if sub_f else ""}{lk}' |
|||
r.append(sflk) |
|||
|
|||
if hasattr(lv, 'class_lookups'): |
|||
r += get_keys_lookups(lv.class_lookups, sflk) |
|||
|
|||
if hasattr(lv, 'output_field'): |
|||
r.append(f'{sflk}{"__" if sflk else ""}range') |
|||
|
|||
r += get_keys_lookups(lv.output_field.class_lookups, sflk) |
|||
|
|||
return r |
|||
|
|||
fields[f_str] = list( |
|||
set(get_keys_lookups(f.class_lookups, ''))) |
|||
|
|||
# Remove excluded fields |
|||
exclude = exclude or [] |
|||
|
|||
fields = [(f, lookups) |
|||
for f, lookups in fields.items() if f not in exclude] |
|||
|
|||
return OrderedDict(fields) |
|||
|
|||
@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 |
Loading…
Reference in new issue