[Django]-Using Django Admin search engine in my own views

4๐Ÿ‘

โœ…

I managed to build my own generical search that works like the admin search. The class is as follows:

from django.db.models import Q
from django.db.models.query import QuerySet
import operator

def django_admin_keyword_search(model, keywords, search_fields):
    """Search according to fields defined in Admin's search_fields"""
    all_queries = None

    for keyword in keywords.split(' '):  #breaks query_string into 'Foo' and 'Bar'
        keyword_query = None

        for field in search_fields:
            each_query = Q(**{field+'__icontains':keyword})

            if not keyword_query:
                keyword_query = each_query
            else:
                keyword_query = keyword_query | each_query

        if not all_queries:
            all_queries = keyword_query
        else:
            all_queries = all_queries & keyword_query

    result_set = model.objects.filter(all_queries).distinct()

    return result_set

Enjoy !!

๐Ÿ‘คmarcelosalloum

0๐Ÿ‘

This already has a working answer by the questions author. However, if you want to use the same search as used by the admin directly in your view, you can do the following:

from django.contrib import admin
from my_app.admin import MyModelAdmin
from my_app.model import MyModel


def my_view(request):
    user_query = request.GET.get("q", "")  # or however you get the user's query
    model_admin = MyModelAdmin(MyModel, admin.site)
    queryset = MyModelAdmin.get_queryset(request)
    results, _ = model_admin.get_search_results(request, queryset, user_query)

results then is a queryset with MyModel objects. Note that we discard the second return value which is a boolean indicating whether there might be duplicates in the queryset.

The use of get_queryset(request) makes sure, that the user set on the request has the proper permissions to view the model instances. You could alternatively use MyModel.objects here if you are sure there are no permission issues.

Using this you can actually get rid of request, e.g. if you are not in a view context, as ModelAdmin (currently) does not actually use it. This might break in the future, but a minimal example for using the admin search is:

model_admin = MyModelAdmin(MyModel, admin.site)
results, _ = model_admin.get_search_results(None, MyModel.objects, "some query")
๐Ÿ‘คvlz

Leave a comment