Created
February 7, 2013 02:17
-
-
Save nkryptic/4727865 to your computer and use it in GitHub Desktop.
A proof of concept for a multifield filter for django-filter. The logic is primarily based on the search mechanism from Django's admin.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import operator | |
from django.db.models import Q | |
from django_filters import CharFilter | |
class MultiFieldFilter(CharFilter): | |
""" | |
This filter preforms an OR query on the defined fields from a | |
single entered value. | |
The following will work similar to the default UserAdmin search:: | |
class UserFilterSet(FilterSet): | |
search = MultiFieldFilter(['username', 'first_name', | |
'last_name', 'email']) | |
class Meta: | |
model = User | |
fields = ['search'] | |
""" | |
def __init__(self, fields, *args, **kwargs): | |
super(MultiFieldFilter, self).__init__(*args, **kwargs) | |
self.fields = fields | |
self.lookup_type = 'icontains' | |
self.lookup_types = [ | |
('^', 'istartswith'), | |
('=', 'iexact'), | |
('@', 'search'), | |
] | |
def filter(self, qs, value): | |
if not self.fields or not value: | |
return qs | |
lookups = [self._get_lookup(str(field)) for field in self.fields] | |
queries = [Q(**{lookup: value}) for lookup in lookups] | |
qs = qs.filter(reduce(operator.or_, queries)) | |
return qs | |
def _get_lookup(self, field_name): | |
for key, lookup_type in self.lookup_types: | |
if field_name.startswith(key): | |
return "%s__%s" % (field_name[len(key):], lookup_type) | |
return "%s__%s" % (field_name, self.lookup_type) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a lot.
I've got a meeting this morning, I'll gave it a try by this afternoon