Skip to content

Commit b4bb25a

Browse files
committed
feat: ajusta carga de lookup e add END em icontains de texto
1 parent ee519cf commit b4bb25a

File tree

1 file changed

+51
-6
lines changed

1 file changed

+51
-6
lines changed

drfautoapi/drfautoapi.py

+51-6
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22
import importlib
33
import inspect
44
import logging
5+
import re
56

67
from django.apps.config import AppConfig
78
from django.apps.registry import apps
89
from django.conf import settings
910
from django.contrib.postgres.fields.jsonb import JSONField
1011
from django.db.models.base import ModelBase
12+
from django.db.models.fields import TextField, CharField
1113
from django.db.models.fields.files import FileField
1214
from django.template.defaultfilters import capfirst
1315
from django.utils.translation import ugettext_lazy as _
1416
import django_filters
15-
from django_filters.constants import ALL_FIELDS
17+
from django_filters.constants import ALL_FIELDS, EMPTY_VALUES
1618
from django_filters.filters import CharFilter
1719
from django_filters.filterset import FilterSet
1820
from django_filters.rest_framework.backends import DjangoFilterBackend
@@ -26,6 +28,43 @@
2628
logger = logging.getLogger(__name__)
2729

2830

31+
class SplitStringCharFilter(django_filters.CharFilter):
32+
_re = re.compile(r'("[^"]+"| +|[^"]+)')
33+
34+
def filter(self, qs, value):
35+
if value in EMPTY_VALUES:
36+
return qs
37+
if self.distinct:
38+
qs = qs.distinct()
39+
lookup = '%s__%s' % (self.field_name, self.lookup_expr)
40+
41+
values = [value]
42+
if self.lookup_expr == 'icontains':
43+
if not '"' in value:
44+
values = value.split(' ')
45+
else:
46+
values = list(
47+
filter(
48+
lambda x: x and x != ' ' and x[0] != '"',
49+
self._re.findall(value)
50+
)
51+
) + list(
52+
map(
53+
lambda x: x[1:-1],
54+
filter(
55+
lambda x: x and x[0] == '"',
56+
self._re.findall(value)
57+
)
58+
)
59+
)
60+
61+
if not isinstance(values, list):
62+
values = [values]
63+
for v in values:
64+
qs = self.get_method(qs)(**{lookup: v})
65+
return qs
66+
67+
2968
class ApiFilterSetMixin(FilterSet):
3069

3170
o = CharFilter(method='filter_o')
@@ -39,6 +78,12 @@ class Meta:
3978
'lookup_expr': 'exact',
4079
},
4180
},
81+
CharField: {
82+
'filter_class': SplitStringCharFilter,
83+
},
84+
TextField: {
85+
'filter_class': SplitStringCharFilter,
86+
},
4287
JSONField: {
4388
'filter_class': django_filters.CharFilter,
4489
'extra': lambda f: {
@@ -81,24 +126,24 @@ def get_keys_lookups(cl, sub_f):
81126
r = []
82127
for lk, lv in cl.items():
83128

84-
if lk == 'contained_by':
129+
if lk in ('contained_by', 'trigram_similar', 'unaccent', 'search'):
85130
continue
86131

87132
sflk = f'{sub_f}{"__" if sub_f else ""}{lk}'
88133
r.append(sflk)
89134

90-
if hasattr(lv, 'class_lookups'):
91-
r += get_keys_lookups(lv.class_lookups, sflk)
135+
if hasattr(lv, 'get_lookups'):
136+
r += get_keys_lookups(lv.get_lookups(), sflk)
92137

93-
if hasattr(lv, 'output_field') and hasattr(lv, 'output_field.class_lookups'):
138+
if hasattr(lv, 'output_field') and hasattr(lv, 'output_field.get_lookups'):
94139
r.append(f'{sflk}{"__" if sflk else ""}range')
95140

96141
r += get_keys_lookups(lv.output_field.class_lookups, sflk)
97142

98143
return r
99144

100145
fields[f_str] = list(
101-
set(fields[f_str] + get_keys_lookups(f.class_lookups, '')))
146+
set(fields[f_str] + get_keys_lookups(f.get_lookups(), '')))
102147

103148
# Remove excluded fields
104149
exclude = exclude or []

0 commit comments

Comments
 (0)