Поиск по нескольким словам через одно поле формы django

Hej!

У меня есть таблица результатов, в которой я могу фильтровать записи через форму django. Например: страна: 'Швеция'

Где я должен получить все записи, где 'Sweden' является значением в столбце 'country'.

Я хочу, чтобы если я введу 'Sweden, Germany', то получу все результаты, где страна в моей базе данных - 'Sweden' или 'Germany'. Булевый ввод ('Швеция ИЛИ/AND Германия') также был бы замечательным!

Вот мой текущий взгляд:

#views.py
def search_institution(request):
    if request.method == "POST":
        form = SearchInstitutionsForm(request.POST)
        if form.is_valid():
            query_set = Institution.objects.filter(
                name__contains=form.cleaned_data['name']
               )
            context = {
                "result_data": list(query_set.values()),
                'form': form
            }
            return render(request, "search_form.html", context)
    else:
        form = SearchInstitutionsForm()

    context = {
        "result_data": list(Institution.objects.values()),
        "form": form
    }
    return render(request, "search_form.html", context)

Я пытался:

query_set = Institution.objects.filter(name__contains=x) for x in ['name']))
query_set = Institution.objects.filter(
                name__search=form.cleaned_data['name']
               )

Здесь я получил ошибку: >Unsupported lookup 'search' for CharField or join on the field not permitted.

Поставил django.contrib.postgres.search в настройках в установленных приложениях и теперь выдает ошибку >unrecognized token: "@"

Моя форма и шаблон:

#forms.py
class SearchInstitutionsForm(forms.Form):
    name = forms.CharField(label='Name', required=False)
#search_form.html
<form method="post">
  {{ form.as_table }}
  {% csrf_token %}
  <input type="submit" value="Search">
</form>

Есть идеи, как решить мою проблему? Спасибо за помощь! :)

Здесь вы можете использовать функцию Q. Сначала разделите два ключевых слова.

split = form.cleaned_data['name'].split(' ')
lookup = Q(name__contains=split[0]) | Q(name__contains=split[1])
query_set = Institution.objects.filter(
                    lookup
                   )

измените свой набор запросов с помощью приведенного выше кода.

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

Мы хотим получить все те строки, которые содержат любое из имен, разделенных запятой. Поэтому мы хотели бы иметь OR условие.

from django.db.models import Q

def get_lookup_query(names_str):
    # Assuring names_str is not empty string i.e ""
    # Also it cannot contain white space only i.e "   "
    assert len(names_str.strip()) > 0, "names_str can neither be empty string nor contain white spaces only"

    # Splitting names based on comma and stripping white spaces 
    # from front and back for each name.
    names_list = [n.strip() for n in names_str.split(',')]

    # It would be good to have case insensitive match
    lookup_query = Q(name__icontains = names_list[0])
    len_names_list = len(names_list)
    if len_names_list > 1:
        for i in range(1,len_names_list):
            lookup_query |= Q(name__icontains = names_list[i])

    return lookup_query

Теперь вы можете получить набор запросов, используя следующее

names_str = form.cleaned_data['name']
lookup_query = get_lookup_query(names_str)
query_set = Institution.objects.filter(lookup_query)

Спасибо за помощь и идеи!

Я исправил свою проблему, написав новую функцию для разделения строки в моем forms.py внутри моей SearchInstitutionForm().

 def clean_name(self):
        name_str = self.cleaned_data["name"]
        if not name_str:
            return []
        name_list = [string.strip() for string in name_str.split(",")]
        return name_list

и добавил отдельную функцию запроса, чтобы сохранить более чистый и простой код в моем views.py. Мои представления и запросы стали довольно сложными :D

Теперь я могу добавить аналогичные функции для всех необходимых частей.

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