From 7647ede3338a541cdc21fd5afb7a1b5258d31e16 Mon Sep 17 00:00:00 2001 From: Jon Farz Date: Thu, 10 Jan 2019 15:52:38 -0500 Subject: [PATCH 1/4] Add the ability to filter by all available fields of a model with modelviewset and djangorestframework filter_fields='__all__'. --- url_filter/integrations/drf.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/url_filter/integrations/drf.py b/url_filter/integrations/drf.py index b2d9960..d144e47 100644 --- a/url_filter/integrations/drf.py +++ b/url_filter/integrations/drf.py @@ -87,6 +87,23 @@ def get_filter_class(self, view, queryset=None): if filter_class: return filter_class + if filter_fields == '__all__': + model = filter_class_default.filter_backend_class(queryset).get_model() + all_fields = list(map(lambda x: x.attname, getattr(model, '_meta').fields)) + + meta_kwargs = filter_class_meta_kwargs.copy() + meta_kwargs.update({ + 'model': model, + 'fields': all_fields, + }) + meta = type(str('Meta'), (object,), meta_kwargs) + + return type( + str('{}FilterSet'.format(model.__name__)), + (filter_class_default,), + {'Meta': meta} + ) + if filter_fields: model = filter_class_default.filter_backend_class(queryset).get_model() From ffc2f42d786e2b6698bf0e70ea04dc36dd96612d Mon Sep 17 00:00:00 2001 From: Jon Farz Date: Fri, 11 Jan 2019 15:39:43 -0500 Subject: [PATCH 2/4] taking @miki725 advice and pushing his change to repo for review --- url_filter/filtersets/base.py | 7 ++++--- url_filter/integrations/drf.py | 17 ----------------- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/url_filter/filtersets/base.py b/url_filter/filtersets/base.py index ba5bb65..9f1c53c 100644 --- a/url_filter/filtersets/base.py +++ b/url_filter/filtersets/base.py @@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals + import abc import re from collections import defaultdict @@ -18,14 +19,12 @@ from ..filters import BaseFilter from ..utils import LookupConfig - __all__ = [ 'FilterSet', 'FilterSetOptions', 'ModelFilterSetOptions', ] - LOOKUP_RE = re.compile( r'^(?:[^\d\W]\w*)(?:{}?[^\d\W]\w*)*(?:!)?$' r''.format(LOOKUP_SEP), re.IGNORECASE @@ -54,6 +53,7 @@ class FilterSetOptions(object): Base class for handling options passed to :class:`.FilterSet` via ``Meta`` attribute. """ + def __init__(self, options=None): pass @@ -436,6 +436,7 @@ class ModelFilterSetOptions(FilterSetOptions): extra_kwargs : dict, optional Additional kwargs to be given to auto-generated individual filters """ + def __init__(self, options=None): super(ModelFilterSetOptions, self).__init__(options) self.model = getattr(options, 'model', None) @@ -467,7 +468,7 @@ def get_filters(self): ''.format(name=self.__class__.__name__) ) - if self.Meta.fields is None: + if self.Meta.fields in [None, '__all__']: self.Meta.fields = self._get_model_field_names() state = self._build_state() diff --git a/url_filter/integrations/drf.py b/url_filter/integrations/drf.py index d144e47..b2d9960 100644 --- a/url_filter/integrations/drf.py +++ b/url_filter/integrations/drf.py @@ -87,23 +87,6 @@ def get_filter_class(self, view, queryset=None): if filter_class: return filter_class - if filter_fields == '__all__': - model = filter_class_default.filter_backend_class(queryset).get_model() - all_fields = list(map(lambda x: x.attname, getattr(model, '_meta').fields)) - - meta_kwargs = filter_class_meta_kwargs.copy() - meta_kwargs.update({ - 'model': model, - 'fields': all_fields, - }) - meta = type(str('Meta'), (object,), meta_kwargs) - - return type( - str('{}FilterSet'.format(model.__name__)), - (filter_class_default,), - {'Meta': meta} - ) - if filter_fields: model = filter_class_default.filter_backend_class(queryset).get_model() From 883991f88a9d9c044b4ca0dae79e38ce545d6f8a Mon Sep 17 00:00:00 2001 From: Jon Farz Date: Mon, 14 Jan 2019 10:07:28 -0500 Subject: [PATCH 3/4] Updating authors.rst to add myself and adding a test case to test for passing __all__ --- AUTHORS.rst | 1 + tests/filtersets/test_django.py | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index 9cc1e2c..ec07871 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -15,3 +15,4 @@ Contributors * Ryan O’Hara - https://github.com/ryan-copperleaf * webrunners - https://github.com/webrunners * Simone Pellizzari - https://github.com/simone6021 +* Jonathon Farzanfar - https://github.com/pctSW1 diff --git a/tests/filtersets/test_django.py b/tests/filtersets/test_django.py index 064f850..98158cc 100644 --- a/tests/filtersets/test_django.py +++ b/tests/filtersets/test_django.py @@ -257,6 +257,18 @@ class Meta(object): 'id', 'name', 'a', 'content_type', 'object_id', } + def test_get_filters_using_all(self): + class ModelBFilterSet(ModelFilterSet): + class Meta(object): + model = ModelB + fields = '__all__' + + filters = ModelBFilterSet().get_filters() + + assert set(filters.keys()) == { + 'id', 'name', 'a', 'content_type', 'object_id', + } + def test_get_form_field_for_field(self): fs = ModelFilterSet() From 42fc1c3aa71f51081cafdb5fcf39f082538eea1a Mon Sep 17 00:00:00 2001 From: Miroslav Shubernetskiy Date: Wed, 16 Jan 2019 11:03:24 -0500 Subject: [PATCH 4/4] small whitespace fixes --- url_filter/filtersets/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/url_filter/filtersets/base.py b/url_filter/filtersets/base.py index 9f1c53c..d5b7246 100644 --- a/url_filter/filtersets/base.py +++ b/url_filter/filtersets/base.py @@ -1,6 +1,5 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, print_function, unicode_literals - import abc import re from collections import defaultdict @@ -19,6 +18,7 @@ from ..filters import BaseFilter from ..utils import LookupConfig + __all__ = [ 'FilterSet', 'FilterSetOptions',