Browse Source

feat: ajusta carga de lookup e add END em icontains de texto

pull/3623/head
LeandroJatai 2 years ago
parent
commit
b4bb25ac6c
  1. 57
      drfautoapi/drfautoapi.py

57
drfautoapi/drfautoapi.py

@ -2,17 +2,19 @@ from collections import OrderedDict
import importlib import importlib
import inspect import inspect
import logging import logging
import re
from django.apps.config import AppConfig from django.apps.config import AppConfig
from django.apps.registry import apps from django.apps.registry import apps
from django.conf import settings from django.conf import settings
from django.contrib.postgres.fields.jsonb import JSONField from django.contrib.postgres.fields.jsonb import JSONField
from django.db.models.base import ModelBase from django.db.models.base import ModelBase
from django.db.models.fields import TextField, CharField
from django.db.models.fields.files import FileField from django.db.models.fields.files import FileField
from django.template.defaultfilters import capfirst from django.template.defaultfilters import capfirst
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
import django_filters import django_filters
from django_filters.constants import ALL_FIELDS from django_filters.constants import ALL_FIELDS, EMPTY_VALUES
from django_filters.filters import CharFilter from django_filters.filters import CharFilter
from django_filters.filterset import FilterSet from django_filters.filterset import FilterSet
from django_filters.rest_framework.backends import DjangoFilterBackend from django_filters.rest_framework.backends import DjangoFilterBackend
@ -26,6 +28,43 @@ from rest_framework.viewsets import ModelViewSet
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class SplitStringCharFilter(django_filters.CharFilter):
_re = re.compile(r'("[^"]+"| +|[^"]+)')
def filter(self, qs, value):
if value in EMPTY_VALUES:
return qs
if self.distinct:
qs = qs.distinct()
lookup = '%s__%s' % (self.field_name, self.lookup_expr)
values = [value]
if self.lookup_expr == 'icontains':
if not '"' in value:
values = value.split(' ')
else:
values = list(
filter(
lambda x: x and x != ' ' and x[0] != '"',
self._re.findall(value)
)
) + list(
map(
lambda x: x[1:-1],
filter(
lambda x: x and x[0] == '"',
self._re.findall(value)
)
)
)
if not isinstance(values, list):
values = [values]
for v in values:
qs = self.get_method(qs)(**{lookup: v})
return qs
class ApiFilterSetMixin(FilterSet): class ApiFilterSetMixin(FilterSet):
o = CharFilter(method='filter_o') o = CharFilter(method='filter_o')
@ -39,6 +78,12 @@ class ApiFilterSetMixin(FilterSet):
'lookup_expr': 'exact', 'lookup_expr': 'exact',
}, },
}, },
CharField: {
'filter_class': SplitStringCharFilter,
},
TextField: {
'filter_class': SplitStringCharFilter,
},
JSONField: { JSONField: {
'filter_class': django_filters.CharFilter, 'filter_class': django_filters.CharFilter,
'extra': lambda f: { 'extra': lambda f: {
@ -81,16 +126,16 @@ class ApiFilterSetMixin(FilterSet):
r = [] r = []
for lk, lv in cl.items(): for lk, lv in cl.items():
if lk == 'contained_by': if lk in ('contained_by', 'trigram_similar', 'unaccent', 'search'):
continue continue
sflk = f'{sub_f}{"__" if sub_f else ""}{lk}' sflk = f'{sub_f}{"__" if sub_f else ""}{lk}'
r.append(sflk) r.append(sflk)
if hasattr(lv, 'class_lookups'): if hasattr(lv, 'get_lookups'):
r += get_keys_lookups(lv.class_lookups, sflk) r += get_keys_lookups(lv.get_lookups(), sflk)
if hasattr(lv, 'output_field') and hasattr(lv, 'output_field.class_lookups'): if hasattr(lv, 'output_field') and hasattr(lv, 'output_field.get_lookups'):
r.append(f'{sflk}{"__" if sflk else ""}range') r.append(f'{sflk}{"__" if sflk else ""}range')
r += get_keys_lookups(lv.output_field.class_lookups, sflk) r += get_keys_lookups(lv.output_field.class_lookups, sflk)
@ -98,7 +143,7 @@ class ApiFilterSetMixin(FilterSet):
return r return r
fields[f_str] = list( fields[f_str] = list(
set(fields[f_str] + get_keys_lookups(f.class_lookups, ''))) set(fields[f_str] + get_keys_lookups(f.get_lookups(), '')))
# Remove excluded fields # Remove excluded fields
exclude = exclude or [] exclude = exclude or []

Loading…
Cancel
Save