Как я могу заставить форму поиска работать с «Именем Фамилия»

#python #django #search

#python #django #Поиск

Вопрос:

В основном проблема заключается в том, что на данный момент моя панель поиска работает, если я ищу точное «Имя» или точную «Фамилию», однако я бы хотел, чтобы это работало также, если пользователь выполняет поиск «Имя Фамилия» или даже если пользователь неправильно написал имя или фамилию, но хотя бы одиниз двух правильных.

 def search(request):
    query = request.GET.get("q", None)
    qs = DeathAd.objects.all()
    if query is not None:
        qs = qs.filter(
            Q(nome__icontains=query) |
            Q(cognome__icontains=query)
        )
    context = {
        "object_list": qs,
    }
    template = "search.html"
    return render(request, template, context)
  

Ответ №1:

Вы можете .annotate(…) [Django-doc] задать запрос с помощью Concat [Django-doc] name , пробела и cogname :

 from django.db.models import Value
from django.db.models.functions import Concat

qs = qs.annotate(
    full_name=Concat('nome', Value(' '), 'cognome')
).filter(
    Q(nome__icontains=query) |
    Q(cognome__icontains=query) |
    Q(full_name__icontains=query)
)  

(…) или даже если пользователь неправильно написал имя или фамилию, но хотя бы одно из двух верное.

Для этого вам понадобится более продвинутая технология поиска, например, серверная часть Elasticsearch, и вы можете использовать django-haystack [readthedocs] для общения с этими бэкэндами.

Комментарии:

1. Спасибо, сэр, ваше решение, похоже, работает очень хорошо, и ваше предположение было проницательным

2. Есть какие-либо предложения по добавлению пагинатора в это представление?

Ответ №2:

может быть, там есть какой-нибудь python. Почему бы не разделить запрос с помощью ‘ ‘ тире, разделив имя и фамилию в список. Затем создайте пустой список для добавления. Вот так,

 def search(request):
query = request.GET.get("q", None).split(' ')
q_list = []
if query is not None:
    for qs in query:
    result = DeathAd.objects.filter(qs)
    q_list.append(result)
context = {
    "object_list": q_list,
}
template = "search.html"
return render(request, template, context)
  

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