11from __future__ import absolute_import
22from __future__ import unicode_literals
33
4- from copy import copy
54from collections import OrderedDict
65
76try :
1918
2019import django_filters
2120import django_filters .filters
22- from django_filters . filterset import get_model_field
21+ from django_filters import filterset
2322
2423from . import filters
2524
2625
27- class FilterSet (django_filters .FilterSet ):
26+ class FilterSetMetaclass (filterset .FilterSetMetaclass ):
27+ def __new__ (cls , name , bases , attrs ):
28+ new_class = super (FilterSetMetaclass , cls ).__new__ (cls , name , bases , attrs )
29+
30+ # Populate our FilterSet fields with all the possible
31+ # filters for the AllLookupsFilter field.
32+ for name , filter_ in six .iteritems (new_class .base_filters ):
33+ if isinstance (filter_ , filters .AllLookupsFilter ):
34+ model = new_class ._meta .model
35+ field = filterset .get_model_field (model , filter_ .name )
36+
37+ for lookup_type in django_filters .filters .LOOKUP_TYPES :
38+ if isinstance (field , ForeignObjectRel ):
39+ f = new_class .filter_for_reverse_field (field , filter_ .name )
40+ else :
41+ f = new_class .filter_for_field (field , filter_ .name )
42+ f .lookup_type = lookup_type
43+ f = new_class .fix_filter_field (f )
44+
45+ # compute filter name
46+ filter_name = name
47+ # Don't add "exact" to filter names
48+ if lookup_type != 'exact' :
49+ filter_name = LOOKUP_SEP .join ([name , lookup_type ])
50+
51+ new_class .base_filters [filter_name ] = f
52+
53+ return new_class
54+
55+
56+ class FilterSet (six .with_metaclass (FilterSetMetaclass , filterset .FilterSet )):
2857 # In order to support ISO-8601 -- which is the default output for
2958 # DRF -- we need to set up custom date/time input formats.
3059 filter_overrides = {
@@ -39,8 +68,6 @@ class FilterSet(django_filters.FilterSet):
3968 },
4069 }
4170
42- LOOKUP_TYPES = django_filters .filters .LOOKUP_TYPES
43-
4471 def __init__ (self , * args , ** kwargs ):
4572 super (FilterSet , self ).__init__ (* args , ** kwargs )
4673
@@ -52,20 +79,6 @@ def __init__(self, *args, **kwargs):
5279 isnull_filter = filters .BooleanFilter (name = ("%s%sisnull" % (filter_ .name , LOOKUP_SEP )))
5380 self .filters ['%s%s%s' % (filter_ .name , LOOKUP_SEP , 'isnull' )] = isnull_filter
5481
55- elif isinstance (filter_ , filters .AllLookupsFilter ):
56- # Populate our FilterSet fields with all the possible
57- # filters for the AllLookupsFilter field.
58- model = self ._meta .model
59- field = get_model_field (model , filter_ .name )
60- for lookup_type in self .LOOKUP_TYPES :
61- if isinstance (field , ForeignObjectRel ):
62- f = self .filter_for_reverse_field (field , filter_ .name )
63- else :
64- f = self .filter_for_field (field , filter_ .name )
65- f .lookup_type = lookup_type
66- f = self .fix_filter_field (f )
67- self .filters ["%s%s%s" % (name , LOOKUP_SEP , lookup_type )] = f
68-
6982 def get_filters (self ):
7083 """
7184 Build a set of filters based on the requested data. The resulting set
@@ -122,9 +135,10 @@ def qs(self):
122135
123136 return qs
124137
125- def fix_filter_field (self , f ):
138+ @classmethod
139+ def fix_filter_field (cls , f ):
126140 """
127- Fix the filter field based on the lookup type.
141+ Fix the filter field based on the lookup type.
128142 """
129143 lookup_type = f .lookup_type
130144 if lookup_type == 'isnull' :
0 commit comments