AllLookupsFilter by default for specific model field
Eloi-Marin opened this issue · 1 comments
Hi !
I'd like to do something like:
class OrdersFilter(filters.FilterSet):
class Meta:
model = OrderView
fields = '__all__'
@classmethod
def filter_for_lookup(cls, f, lookup_type):
if isinstance(f, models.FloatField):
return filters.AllLookupsFilter, {}
but it is not working :S Is there any reason for that ? I am doing the same for DateFields in order to activare range filtering for any date and it works well.
if isinstance(f, models.DateField):
return DateRangeRangeFilter, {'lookup_expr': 'range'}
if isinstance(f, models.CharField):
return ChoicesInFilter, {'lookup_expr': 'in'}
Also, would there be a way to set the allowed lookup_expr for AllLookupsFilter, something like
if isinstance(f, models.FloatField):
return filters.AllLookupsFilter, {'lookup_expr': ['gt','lt','gte','lte','exact']}
Thanks!!
(@rpkilby) edited for formatting
Hi @Eloi-Marin. I can't dive into an in-depth explanation at the moment, but the short version is:
- None of the magic occurs within
AllLookupsFilter
- it doesn't implement any real functionality. Instead, these filters act like a... virtual filter (?)... that is processed by the filterset and converted into the 20 or 30 concrete filters (one for each lookup supported by that model field). - Overriding
filter_for_lookup
to returnAllLookupsFilter
occurs too late. At this point, theAllLookupsFilter
instances have already been expanded into the concrete filters, and they are not processed any further.
In general, AllLookupsFilter
is useful for prototyping, but I highly recommend against using it in production code. Writing code that generates AllLookupsFilter
s should be avoided. The real solution here is to use the Meta.fields
dict syntax.
class OrdersFilter(filters.FilterSet):
class Meta:
model = Order
fields = {
'date_field': ['exact', '...'],
'float_field': ['etc', '...'],
}
If you're not a fan of copy+pasting the list of lookups for every field, then just create a few common lists
DATE_LOOKUPS = ['...']
FLOAT_LOOKUPS = ['...']
class OrdersFilter(filters.FilterSet):
class Meta:
model = Order
fields = {
'date_field': DATE_LOOKUPS,
'float_field': FLOAT_LOOKUPS,
}