HAOYANG MI
HAOYANG MI

Reputation: 151

Advanced search in Django using python

I am currently working on django. Now, I want achieve the advanced search, to be more specifically, achieve precise searching using imprecise key words.

For example, when I type 'a$c', all the matching results will be 'ac', 'abc', 'a!c', 'Ac', 'AC' and so on. Basically, '$(or maybe other characters)' could be numbers, could be letters or nothing. Is there any method to do this? BTW, my code for achieving the basic search function is written as below:

class MetaboliteAdmin(admin.ModelAdmin):
    search_fields = ['id', 'name', 'compartment', 'charge', 'formula']

class ReactionAdmin(admin.ModelAdmin):
    search_fields = ['id', 'name','metabolites', 'gene_reaction_rule', 'subsystem']

class GeneAdmin(admin.ModelAdmin):
    search_fields = ['id', 'name', ''] 

Upvotes: 1

Views: 1561

Answers (1)

Will Keeling
Will Keeling

Reputation: 23004

You can override get_search_results() in a ModelAdmin class to give you more control over object search functionality.

The example below uses Django's iregex lookup to do a case-insensitive search across all search_fields when the $ character is specified. It basically replaces the $ with a .* which is regex for "any character, zero or more times".

from functools import reduce
from django.db.models import Q

class MetaboliteAdmin(admin.ModelAdmin):
    search_fields = ['id', 'name', 'compartment', 'charge', 'formula']

    def get_search_results(self, request, queryset, search_term):
        if '$' in search_term:
            search_term = search_term.replace('$', '.*')
            return queryset.filter(reduce(lambda x, y: x | y,
                                          [Q(**{'{}__iregex'.format(field): search_term})
                                           for field in self.search_fields])), True
        return super().get_search_results(request, queryset, search_term)

When the $ character is not specified, the search functionality behaves as normal.

Upvotes: 3

Related Questions