Skip to content

Commit

Permalink
linting fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
SunnyR committed Jun 7, 2024
1 parent e12f7b8 commit 438e584
Show file tree
Hide file tree
Showing 29 changed files with 1,201 additions and 905 deletions.
8 changes: 5 additions & 3 deletions rest_framework_filters/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class RestFrameworkFilterBackend(backends.DjangoFilterBackend):

@property
def template(self):
return 'rest_framework_filters/form.html'
return "rest_framework_filters/form.html"

@contextmanager
def patch_for_rendering(self, request):
Expand Down Expand Up @@ -48,7 +48,7 @@ def to_html(self, request, queryset, view):


class ComplexFilterBackend(RestFrameworkFilterBackend):
complex_filter_param = 'filters'
complex_filter_param = "filters"
operators = None
negation = True

Expand All @@ -70,7 +70,9 @@ def filter_queryset(self, request, queryset, view):
# Collect the individual filtered querysets
querystrings = [op.querystring for op in complex_ops]
try:
querysets = self.get_filtered_querysets(querystrings, request, queryset, view)
querysets = self.get_filtered_querysets(
querystrings, request, queryset, view
)
except ValidationError as exc:
raise ValidationError({self.complex_filter_param: exc.detail})

Expand Down
24 changes: 13 additions & 11 deletions rest_framework_filters/complex_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@
# current iteration: https://regex101.com/r/5rPycz/3
# special thanks to @JohnDoe2 on the #regex IRC channel!
# matches groups of "<negate>(<encoded querystring>)<set op>"
COMPLEX_OP_RE = re.compile(r'()\(([^)]+)\)([^(]*?(?=\())?')
COMPLEX_OP_NEG_RE = re.compile(r'(~?)\(([^)]+)\)([^(]*?(?=~\(|\())?')
COMPLEX_OP_RE = re.compile(r"()\(([^)]+)\)([^(]*?(?=\())?")
COMPLEX_OP_NEG_RE = re.compile(r"(~?)\(([^)]+)\)([^(]*?(?=~\(|\())?")
COMPLEX_OPERATORS = {
'&': QuerySet.__and__,
'|': QuerySet.__or__,
"&": QuerySet.__and__,
"|": QuerySet.__or__,
}

ComplexOp = namedtuple('ComplexOp', ['querystring', 'negate', 'op'])
ComplexOp = namedtuple("ComplexOp", ["querystring", "negate", "op"])


def decode_complex_ops(encoded_querystring, operators=None, negation=True):
Expand Down Expand Up @@ -61,25 +61,27 @@ def decode_complex_ops(encoded_querystring, operators=None, negation=True):

if not matches:
msg = _("Unable to parse querystring. Decoded: '%(decoded)s'.")
raise ValidationError(msg % {'decoded': decoded_querystring})
raise ValidationError(msg % {"decoded": decoded_querystring})

results, errors = [], []
for match, has_next in lookahead(matches):
negate, querystring, op = match.groups()

negate = negate == '~'
negate = negate == "~"
querystring = unquote(querystring)
op_func = operators.get(op.strip()) if op else None
if op_func is None and has_next:
msg = _("Invalid querystring operator. Matched: '%(op)s'.")
errors.append(msg % {'op': op})
errors.append(msg % {"op": op})

results.append(ComplexOp(querystring, negate, op_func))

msg = _("Ending querystring must not have trailing characters. Matched: '%(chars)s'.")
trailing_chars = decoded_querystring[matches[-1].end():]
msg = _(
"Ending querystring must not have trailing characters. Matched: '%(chars)s'."
)
trailing_chars = decoded_querystring[matches[-1].end() :] # noqa: E203
if trailing_chars:
errors.append(msg % {'chars': trailing_chars})
errors.append(msg % {"chars": trailing_chars})

if errors:
raise ValidationError(errors)
Expand Down
12 changes: 6 additions & 6 deletions rest_framework_filters/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

from django.utils.module_loading import import_string
from django_filters.rest_framework.filters import * # noqa
from django_filters.rest_framework.filters import (
ModelChoiceFilter, ModelMultipleChoiceFilter,
)
from django_filters.rest_framework.filters import (ModelChoiceFilter,
ModelMultipleChoiceFilter)

ALL_LOOKUPS = '__all__'
ALL_LOOKUPS = "__all__"


class AutoFilter:
Expand Down Expand Up @@ -76,7 +75,7 @@ class creation time, instead of during initialization.
Args:
filterset: The filterset to bind
"""
if not hasattr(self, 'bound_filterset'):
if not hasattr(self, "bound_filterset"):
self.bound_filterset = filterset

def filterset():
Expand All @@ -87,14 +86,15 @@ def fget(self):
self._filterset = import_string(self._filterset)
except ImportError:
# Fallback to building import path relative to bind class
path = '.'.join([self.bound_filterset.__module__, self._filterset])
path = ".".join([self.bound_filterset.__module__, self._filterset])
self._filterset = import_string(path)
return self._filterset

def fset(self, value):
self._filterset = value

return locals()

filterset = property(**filterset())

def get_queryset(self, request):
Expand Down
45 changes: 26 additions & 19 deletions rest_framework_filters/filterset.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,17 @@ def related(filterset, filter_name):

class FilterSetMetaclass(filterset.FilterSetMetaclass):
def __new__(cls, name, bases, attrs):
attrs['auto_filters'] = cls.get_auto_filters(bases, attrs)
attrs["auto_filters"] = cls.get_auto_filters(bases, attrs)

new_class = super().__new__(cls, name, bases, attrs)

new_class.related_filters = OrderedDict([
(name, f) for name, f in new_class.declared_filters.items()
if isinstance(f, filters.BaseRelatedFilter)])
new_class.related_filters = OrderedDict(
[
(name, f)
for name, f in new_class.declared_filters.items()
if isinstance(f, filters.BaseRelatedFilter)
]
)

# See: :meth:`rest_framework_filters.filters.RelatedFilter.bind`
for f in new_class.related_filters.values():
Expand Down Expand Up @@ -54,17 +58,17 @@ def get_auto_filters(cls, bases, attrs):

# Default the `filter.field_name` to the attribute name on the filterset
for filter_name, f in auto_filters:
if getattr(f, 'field_name', None) is None:
if getattr(f, "field_name", None) is None:
f.field_name = filter_name

auto_filters.sort(key=lambda x: x[1].creation_counter)

# merge auto filters from base classes
for base in reversed(bases):
if hasattr(base, 'auto_filters'):
if hasattr(base, "auto_filters"):
auto_filters = [
(name, f) for name, f
in base.auto_filters.items()
(name, f)
for name, f in base.auto_filters.items()
if name not in attrs
] + auto_filters

Expand Down Expand Up @@ -108,8 +112,9 @@ def expand_auto_filter(cls, new_class, filter_name, f):

if gen_f.lookup_expr != "exact":
# Update field name to also include lookup expr.
gen_f.field_name = "{field_name}__{lookup_expr}".format(field_name=f.field_name,
lookup_expr=gen_f.lookup_expr)
gen_f.field_name = "{field_name}__{lookup_expr}".format(
field_name=f.field_name, lookup_expr=gen_f.lookup_expr
)

# do not overwrite declared filters
if gen_name not in orig_declared:
Expand Down Expand Up @@ -197,8 +202,9 @@ def disable_subset(cls, *, depth=0):
This filterset class with subset disabling mixed in.
"""
if not issubclass(cls, SubsetDisabledMixin):
cls = type('SubsetDisabled%s' % cls.__name__,
(SubsetDisabledMixin, cls), {})
cls = type(
"SubsetDisabled%s" % cls.__name__, (SubsetDisabledMixin, cls), {}
)

# recursively disable subset for related filtersets
if depth > 0:
Expand Down Expand Up @@ -254,16 +260,16 @@ def get_param_filter_name(cls, param, rel=None):
return None

# strip the rel prefix from the param name.
prefix = '%s%s' % (rel or '', LOOKUP_SEP)
prefix = "%s%s" % (rel or "", LOOKUP_SEP)
if rel and param.startswith(prefix):
param = param[len(prefix):]
param = param[len(prefix) :] # noqa: E203

# Attempt to match against filters with lookups first. (username__endswith)
if param in cls.base_filters:
return param

# Attempt to match against exclusion filters
if param[-1] == '!' and param[:-1] in cls.base_filters:
if param[-1] == "!" and param[:-1] in cls.base_filters:
return param[:-1]

# Match against relationships. (author__username__endswith).
Expand All @@ -288,7 +294,7 @@ def get_request_filters(self):
requested_filters[filter_name] = f

# exclusion params
exclude_name = '%s!' % filter_name
exclude_name = "%s!" % filter_name
if related(self, exclude_name) in self.data:
# deepcopy the *base* filter to prevent copying of model & parent
f_copy = copy.deepcopy(self.base_filters[filter_name])
Expand Down Expand Up @@ -341,15 +347,15 @@ def filter_related_filtersets(self, queryset):
"""
for related_name, related_filterset in self.related_filtersets.items():
# Related filtersets should only be applied if they had data.
prefix = '%s%s' % (related(self, related_name), LOOKUP_SEP)
prefix = "%s%s" % (related(self, related_name), LOOKUP_SEP)
if not any(value.startswith(prefix) for value in self.data):
continue

field = self.filters[related_name].field
to_field_name = getattr(field, 'to_field_name', 'pk') or 'pk'
to_field_name = getattr(field, "to_field_name", "pk") or "pk"

field_name = self.filters[related_name].field_name
lookup_expr = LOOKUP_SEP.join([field_name, 'in'])
lookup_expr = LOOKUP_SEP.join([field_name, "in"])

subquery = related_filterset.qs.values(to_field_name)
queryset = queryset.filter(**{lookup_expr: subquery})
Expand All @@ -376,4 +382,5 @@ def clean(form):
self.form.errors[related(related_filterset, key)] = error

return cleaned_data

return Form
8 changes: 4 additions & 4 deletions rest_framework_filters/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def lookups_for_field(model_field):
if issubclass(lookup, Transform):
transform = lookup(Expression(model_field))
lookups += [
LOOKUP_SEP.join([expr, sub_expr]) for sub_expr
in lookups_for_transform(transform)
LOOKUP_SEP.join([expr, sub_expr])
for sub_expr in lookups_for_transform(transform)
]

else:
Expand Down Expand Up @@ -56,8 +56,8 @@ def lookups_for_transform(transform):

sub_transform = lookup(transform)
lookups += [
LOOKUP_SEP.join([expr, sub_expr]) for sub_expr
in lookups_for_transform(sub_transform)
LOOKUP_SEP.join([expr, sub_expr])
for sub_expr in lookups_for_transform(sub_transform)
]

else:
Expand Down
19 changes: 12 additions & 7 deletions tests/perf/filters.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from django_filters import FilterSet as DFFilterSet

from rest_framework_filters import filters
Expand All @@ -12,25 +11,31 @@ class NoteFilterWithExplicitRelated(DFFilterSet):
class Meta:
model = Note
fields = {
'title': [
'exact', 'contains', 'startswith', 'endswith',
'iexact', 'icontains', 'istartswith', 'iendswith',
"title": [
"exact",
"contains",
"startswith",
"endswith",
"iexact",
"icontains",
"istartswith",
"iendswith",
],
'author__username': ['exact'],
"author__username": ["exact"],
}


# drf-filters
class UserFilterWithAll(DRFFilterSet):
username = filters.AutoFilter(lookups='__all__')
username = filters.AutoFilter(lookups="__all__")

class Meta:
model = User
fields = []


class NoteFilterWithRelatedAll(DRFFilterSet):
title = filters.AutoFilter(lookups='__all__')
title = filters.AutoFilter(lookups="__all__")
author = filters.RelatedFilter(UserFilterWithAll, queryset=User.objects.all())

class Meta:
Expand Down
3 changes: 1 addition & 2 deletions tests/perf/serializers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

from rest_framework import serializers

from ..testapp.models import Note
Expand All @@ -7,4 +6,4 @@
class NoteSerializer(serializers.ModelSerializer):
class Meta:
model = Note
fields = ['pk', 'title', 'content', 'author']
fields = ["pk", "title", "content", "author"]
Loading

0 comments on commit 438e584

Please sign in to comment.