Изменить строку запроса, чтобы учесть несколько значений - PullRequest
2 голосов
/ 02 мая 2020

У меня проблема со строкой запроса, проблема в том, что при выборе нескольких значений в моих Django перерывах поиска. Я получаю это в URL ?Query=value1&Query=Value2. В этом сценарии выполняется поиск только последнего значения. Я хочу, чтобы оба значения искались (с эквивалентом оператора AND между ними).

Это желаемый результат ?Query=value1+Value2.

Я добавил свою форму поиска, которая использует Select2, и мой Django вид поиска ниже. Если вам нужно что-нибудь еще, дайте мне сейчас.

Любая помощь будет высоко ценится.

Форма поиска на переднем конце

<form id="makeitso" role="search" action="" method="get">                   
            <select class="js-example-placeholder-multiple" name="query" multiple="multiple">
                <option value="Value 1">Value 1</option>   
                <option value="Value 2">Value 2</option>   
                <option value="Value 3">Value 3</option>     
            </select>

               <script>
                   $(".js-example-placeholder-multiple").select2({
                       placeholder: "Search here",
                   });
               </script>

       <div class="form-inline justify-content-center">
           <button type="submit"  class="btn btn-xlarge">Search</button>
       </div>
   </form>

views.py

def search(request):
        search_query = request.GET.get('query', None)
        page = request.GET.get('page', 1)

        # Search
        if search_query:
            search_results = TestPage.objects.live().search(search_query)
            query = Query.get(search_query)

            # Record hit
            query.add_hit()
        else:
            search_results = TestPage.objects.none()

        # Pagination
        paginator = Paginator(search_results, 3)
        try:
            search_results = paginator.page(page)
        except PageNotAnInteger:
            search_results = paginator.page(1)
        except EmptyPage:
            search_results = paginator.page(paginator.num_pages)

        return render(request, 'search/search.html', {
            'search_query': search_query,
            'search_results': search_results,
        })

Ответы [ 3 ]

1 голос
/ 04 мая 2020

Спасибо за все предложения, они помогли мне, но решение, которое я разработал ниже, является наиболее полезным ответом для всех, кто читает этот вопрос. Приведенный ниже код отлично подходит для моих требований и позволяет искать несколько значений.

Мне удалось использовать метод getlist, а затем модуль functools (используемый для функций более высокого порядка) с помощью Reduce. Оператор допускает and или or, в настоящее время я использую and, который показывает результаты пользователей, которые соответствуют только всем поисковым значениям.

Потребовалось время, чтобы добраться сюда, надеюсь, это поможет другим!

Views.py

def search(request):
    page = request.GET.get('page', 1)

    search_query = request.GET.getlist('query' , None)

    # searches for results that match all values
    query = functools.reduce(operator.and_, (Q(test_body__contains = i) for i in search_query))

    search_results = TestPage.objects.filter(query).distinct().order_by('-latest_revision_created_at') 
1 голос
/ 02 мая 2020

Вам потребуется использовать метод getlist() атрибута GET.

, например: search_query = request.GET.get('query', None)

должно быть

search_query = request.GET.getlist('query', None)

Затем можно выполнить l oop по всем поисковым запросам следующим образом:

for query in search_query:

Затем можно использовать Q Objects для более сложных запросов:

q = Q()
for query in search_query:
    q |= Q(term=query)
ModelToQuery.objects.filter(q)

https://docs.djangoproject.com/en/3.0/ref/request-response/#django .http.QueryDict.getlist

https://docs.djangoproject.com/en/3.0/topics/db/queries/#complex -просмотры с q-объектами

0 голосов
/ 02 мая 2020

Следующий формат должен работать

#Views.py
Edit: from django.db.models import Q

def get_queryset(query=None):
    queryset = []
    queries = query.split(" ") 
    for q in queries:
        page = TestPage.objects.filter(
                Q(obj1__icontains=q) | 
                Q(obj2__icontains=q)
            ).distinct()

        for page in pages:
            queryset.append(page)

    return list(set(queryset))

Таким образом, вы можете l oop просматривать страницы для нескольких различных индикаторов, например, номера страницы или слова. (представлен obj1 и obj2 выше)

Редактировать: query = query.split разделит «пробел» между объектами (словами или числами), чтобы вы могли искать объекты в большом наборе, которое может иметь больше чем один сегмент. то есть, если вы хотите найти «страницу 16» вместо «страница» или «16», вы можете с помощью split. Это будет сделано, если взять каждый сегмент и превратить их в строки в списке с возможностью поиска, чтобы «страница 16» стала ['page', '16'] * ​​1006 *

...