I wish to customize the way in which search queries across the search_fields.
Is there a way to do it without hacking deeply into the Django code or creating a totally independent view?
For instance, I would like to return the union of the querysets for each of the items of the querystring.split(). So that searching for "apple bar" would return results with EITHER apple OR bar, unlike the default search which applies an AND operator.
So I have been using the code from WeizhongTu's answer and found a not-so-obvious error in it. When we try to use both filtering and searching with this code, filtering is shadowed by this line:
queryset = self.model.objects.filter(eval(query_condition))
It is important to use the previous results ONLY. So you must never use self.model.objects
to obtain the queryset, but only filter the queryset itself. Like this:
def get_search_results(self, request, queryset, search_term):
# search_term is what you input in admin site
# queryset is the list of objects passed to you
# by the previous functions, e. g. filtering
search_term_list = search_term.split(' ') #['apple','bar']
search_columns = ('name','age','address')
# convert to Q(name='apple') | Q(name='bar') | Q(age='apple') | ...
query_condition = ' | '.join(['Q(%s="%s")'%(x,y) for x in search_term_list for y in search_columns])
appended_queryset = queryset.filter(eval(query_condition))
# queryset is search results
queryset, use_distinct = super(PersonAdmin, self).get_search_results(request, queryset, search_term)
queryset |= appended_queryset
return queryset, use_distinct
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With