Поиск в нескольких моделях в Django

У меня много различных моделей в Django, и я хочу искать ключевое слово во всех них. Например, если вы искали "blah", я хочу показать все товары с "blah", все счета с "blah", и, наконец, все другие модели с "blah".

Я могу разработать представление и искать во всех моделях отдельно, но это не очень хорошая идея.

Какова наилучшая практика для данной ситуации?

Я сталкивался с такой ситуацией несколько раз, и одним из решений является использование менеджеров моделей и создание отдельных методов поиска для однословных и многословных запросов. Возьмем следующие примеры моделей: Каждая из них имеет свой собственный менеджер моделей с двумя отдельными методами запроса. search будет выполнять однословный поиск по всем полям, а search_and будет выполнять поиск по каждому слову в списке поисковых слов, используя функцию reduce. Оба метода используют объекты Q для выполнения поиска по нескольким полям.

Теперь, чтобы использовать их в представлении поиска, которое вы можете направить на столько менеджеров моделей, сколько пожелаете, которое может запрашивать столько полей, сколько пожелаете. Используя примеры моделей, приведенные выше, вот пример представления, ниже. Он передает поисковый термин или термины соответствующему методу менеджера моделей, основываясь на количестве терминов (либо 1, либо более 1).



def application_search(request):
    data = dict()
    
    if 'query' in request.GET: 
        query_list = request.GET.get("query", None).split()
        if query_list:
            try:
                if len(query_list) > 1:
                    products = Product.objects.search_and(query=query_list)
                    profiles = Profile.objects.search_and(query=query_list)
                else:
                    products = Product.objects.search(query=query_list[0])
                    profiles = Profile.objects.search(query=query_list[0])
            except:
                # Throw exception or log error here 
            try:
                queryset_chain = chain(products, profiles) # combines querysets into one
                results = sorted(queryset_chain, key=lambda instance: instance.id, reverse=True) #sorts results by ID
            except:
                results = None        

        data['results'] = render_to_string('pages/my_search_result_page.html', {'results': results})

        return JsonResponse(data)

В этом представлении query фактически передается на бэкенд через AJAX, но вы можете сделать это иначе, исходя из ваших потребностей и дизайна шаблона.

Вернуться на верх