Ferhat Elmas — Passionate Developer

Generic Search Mixin

29 April ’13

Search capability is an important feature of services since it enables users to efficiently use a large body of information. The amount of data searched dramatically effects the responsive of the interface. Therefore, search is generally goes to its own framework like Solr, Elastic Search, etc. However, if we simply want to filter some objects, at least in the very early stage of development, a generic search mixin would be handy. A sample mixin for Django:

# core/views.py
class SearchMixin(object):
    """Generic query filter for search"""

    search_mapping = {'u': 'username'}  # mapping for attributes to be searched

    def get_queryset(self):
        queryset = super(SearchMixin, self).get_queryset()

        q = self.request.GET.get('q')
        if q:
            typ = self.request.GET.get('t')
            if typ not in self.search_mapping.keys():
                typ = self.search_mapping.keys()[0]
            return queryset.filter(**{self.search_mapping[typ] + '__icontains': q})
        return self.model.objects.none()  # you may return original queryset

Then, we can easily use it with various views in this way:

# profiles/views.py
from django.views.generic import ListView

from core.views import SearchMixin

class ProfileListView(SearchMixin, ListView):
    model = Profile
    paginate_by = 10

Yes, that's it but one small thing to do is writing your search type to be used by SearchMixin such as a hidden field in the following form snippet.

<!-- profiles/profile_list.html -->
<form action="" method="GET">
    <input type="hidden" name="t" value="u" />
    <input type="text" name="q" />

    <p><input type="submit" class="btn btn-primary" value="Search" /></p>
</form>