Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to search for multiple terms in admin search? django

In the django admin search bar if i had a model with a column = fruit_name and I wanted to search that column for all instances with either the fruit_name = banana or apple which would show all of the bananas and apples, how could I do that?

like image 356
user3806832 Avatar asked Jan 22 '15 22:01

user3806832


2 Answers

Override the ModelAdmin.get_search_results` method:

from operator import or_
from django.db.models import Q

class MyAdmin(admin.ModelAdmin):
    ...
    def get_search_results(self, request, queryset, search_term):
        queryset, use_distinct = super(MyAdmin, self).get_search_results(
                                               request, queryset, search_term)
        search_words = search_term.split()
        if search_words:
            q_objects = [Q(**{field + '__icontains': word})
                                for field in self.search_fields
                                for word in search_words]
            queryset |= self.model.objects.filter(reduce(or_, q_objects))
    return queryset, use_distinct
like image 151
catavaran Avatar answered Oct 11 '22 15:10

catavaran


In my case, using @catavaran's answer would break filters as asked here. I came up with the following work-around:

from operator import or_
from django.db.models import Q

class MyAdmin(admin.ModelAdmin):
    ...
    def get_search_results(self, request, queryset, search_term):
        orig_queryset = queryset
        queryset, use_distinct = super(MyAdmin, self).get_search_results(
                                               request, queryset, search_term)
        search_words = search_term.split()
        if search_words:
            q_objects = [Q(**{field + '__icontains': word})
                                for field in self.search_fields
                                for word in search_words]
            queryset |= self.model.objects.filter(reduce(or_, q_objects))

    queryset = queryset & orig_queryset

    return queryset, use_distinct

This makes sure that ant previous filtering is not overridden when we use queryset |= self.model.objects.filter(reduce(or_, q_objects)). The use of orig_queryset, on the other hand, ensures that any chosen filters also get applied.

like image 42
Stunts Avatar answered Oct 11 '22 13:10

Stunts